Start · Sprachen · JavaScript · Referenz · BarcodeDetector

BarcodeDetector

Schnittstelle

Die Schnittstelle <code>BarcodeDetector</code> gehört zur Barcode Detection API. Sie erkennt ein- und zweidimensionale Barcodes (z. B. QR, EAN-13, Code 128) in Bildern, Videos und Canvas-Elementen.

seit JavaScript Experimentell: Chrome/Edge 83+ (Android, macOS, Ch Kategorie: webapi

Signatur

interface BarcodeDetector

Beschreibung

Mit BarcodeDetector liest du Barcodes direkt im Browser aus, ohne eine eigene JavaScript-Bibliothek zu laden. Die Erkennung übernimmt das Betriebssystem oder der Browser, meist mit Hardware-Beschleunigung. Das ist schneller und spart Akku im Vergleich zu reinen JS- oder WebAssembly-Lösungen. Typische Einsatzfälle sind QR-Code-Scanner in Web-Apps, Warenwirtschaft und Lagerverwaltung, Ticket-Kontrolle oder das Einlesen von Produkt-EANs mit der Handykamera.

Du erzeugst eine Instanz mit new BarcodeDetector({ formats }). Mit formats legst du fest, nach welchen Barcode-Typen gesucht wird. Die wichtigste Methode ist detect(image). Sie nimmt eine Bildquelle entgegen (ImageBitmapSource: z. B. HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, ImageBitmap, ImageData, Blob, VideoFrame, OffscreenCanvas). Sie gibt ein Promise mit einem Array von DetectedBarcode-Objekten zurück. Jedes Objekt enthält:

  • rawValue: den dekodierten Inhalt als String
  • format: das erkannte Format
  • boundingBox: ein DOMRectReadOnly mit der Position im Bild
  • cornerPoints: die vier Eckpunkte des Barcodes

Die statische Methode BarcodeDetector.getSupportedFormats() liefert die Formate, die auf dem aktuellen Gerät tatsächlich unterstützt werden. Frag sie vor dem Konstruktor ab, denn welche Formate verfügbar sind, hängt von Plattform und Betriebssystem ab. Mögliche Werte sind aztec, code_128, code_39, code_93, codabar, data_matrix, ean_13, ean_8, itf, pdf417, qr_code, upc_a, upc_e und unknown.

Für einen Live-Scanner kombinierst du die API mit navigator.mediaDevices.getUserMedia(). Das Kamerabild wird in einem <video>-Element angezeigt, und detect() wird regelmäßig aufgerufen, z. B. per requestAnimationFrame() oder requestVideoFrameCallback().

Parameter

Name Typ Default Beschreibung
$options { formats?: string[] } alle unterstützten Formate Optionales Konfigurationsobjekt für den Konstruktor. formats ist ein Array mit den Barcode-Formaten, nach denen gesucht werden soll, z. B. ['qr_code', 'ean_13']. Bei einem leeren Array oder einem unbekannten Format wird ein TypeError geworfen.

Rückgabewert

Typ
BarcodeDetector
Beschreibung
Eine neue BarcodeDetector-Instanz. Ihre Methode detect(image) gibt ein Promise<DetectedBarcode[]> zurück.

Beispiele

Unterstützung und verfügbare Formate prüfen

const initDetector = async () => {
  if (!('BarcodeDetector' in globalThis)) {
    console.warn('Barcode Detection API wird nicht unterstützt.');
    return null;
  }
  const formats = await BarcodeDetector.getSupportedFormats();
  console.log('Unterstützte Formate:', formats);

  // Nur Formate anfordern, die das Gerät auch wirklich kann
  const wanted = ['qr_code', 'ean_13'].filter((f) => formats.includes(f));
  if (wanted.length === 0) return null;

  return new BarcodeDetector({ formats: wanted });
};

const detector = await initDetector();
Unterstützte Formate: ['aztec', 'code_128', 'ean_13', 'qr_code', ...]

Barcode aus einem hochgeladenen Bild lesen

// <input type="file" id="upload" accept="image/*">
const detector = new BarcodeDetector({ formats: ['qr_code', 'ean_13', 'code_128'] });

document.querySelector('#upload').addEventListener('change', async (event) => {
  const file = event.target.files[0];
  if (!file) return;

  const bitmap = await createImageBitmap(file);
  const barcodes = await detector.detect(bitmap);
  bitmap.close();

  if (barcodes.length === 0) {
    console.log('Kein Barcode gefunden.');
    return;
  }
  for (const { format, rawValue, boundingBox } of barcodes) {
    console.log(`${format}: ${rawValue} @ x=${Math.round(boundingBox.x)}, y=${Math.round(boundingBox.y)}`);
  }
});
qr_code: https://programmierung.net @ x=112, y=87

Live-QR-Scanner mit der Kamera

// <video id="cam" autoplay playsinline muted></video>
const video = document.querySelector('#cam');
const detector = new BarcodeDetector({ formats: ['qr_code'] });

const stream = await navigator.mediaDevices.getUserMedia({
  video: { facingMode: 'environment' }
});
video.srcObject = stream;
await video.play();

const scan = async () => {
  try {
    const [code] = await detector.detect(video);
    if (code) {
      console.log('Gescannt:', code.rawValue);
      stream.getTracks().forEach((t) => t.stop()); // Kamera freigeben
      return;
    }
  } catch (err) {
    console.error('Erkennung fehlgeschlagen:', err);
  }
  requestAnimationFrame(scan);
};

requestAnimationFrame(scan);
Gescannt: WIFI:S:MeinNetz;T:WPA;P:geheim;;

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die API ist experimentell und kein Baseline-Feature. Chromium-Browser unterstützen sie unter Android, macOS und ChromeOS. Unter Windows und Linux fehlt die Plattform-Unterstützung oft, dann liefert getSupportedFormats() ein leeres Array. Firefox und Safari auf dem Desktop unterstützen die API nicht. Prüfe sie deshalb immer mit 'BarcodeDetector' in globalThis und halte einen Ersatz bereit, z. B. eine Bibliothek wie ZXing oder ein Polyfill auf WebAssembly-Basis.
  • Sicherer Kontext: Die API ist nur über HTTPS bzw. localhost verfügbar. Für den Kamerazugriff mit getUserMedia() muss der Nutzer außerdem die Berechtigung erteilen.
  • Formate: Ein leeres formats-Array oder ein unbekanntes Format führt zu einem TypeError. Ein Format, das zwar gültig ist, aber vom Gerät nicht unterstützt wird, wird dagegen stillschweigend nicht erkannt. Gleiche die Formate daher vorher mit getSupportedFormats() ab.
  • Performance: Rufe detect() nicht erneut auf, solange das vorige Promise noch aussteht. Bremse die Aufrufe in Scan-Schleifen, z. B. alle 100–200 ms oder per requestVideoFrameCallback(). Nicht mehr benötigte ImageBitmap-Objekte gibst du mit close() frei.
  • Sicherheit: rawValue ist eine unkontrollierte Benutzereingabe. Setze den Wert nie ungeprüft per innerHTML ein, sonst droht XSS. Leite auch nicht automatisch auf gescannte URLs weiter, sonst droht Phishing per präpariertem QR-Code. Verwende textContent und prüfe URLs vorher.
  • Bilder von fremden Domains ohne CORS-Freigabe (tainted canvas) führen zu einem SecurityError.