Signatur
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 Stringformat: das erkannte FormatboundingBox: einDOMRectReadOnlymit der Position im BildcornerPoints: 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
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();
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)}`);
}
});
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);
// 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 globalThisund 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.
localhostverfügbar. Für den Kamerazugriff mitgetUserMedia()muss der Nutzer außerdem die Berechtigung erteilen. - Formate: Ein leeres
formats-Array oder ein unbekanntes Format führt zu einemTypeError. 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 mitgetSupportedFormats()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 perrequestVideoFrameCallback(). Nicht mehr benötigteImageBitmap-Objekte gibst du mitclose()frei. - Sicherheit:
rawValueist eine unkontrollierte Benutzereingabe. Setze den Wert nie ungeprüft perinnerHTMLein, sonst droht XSS. Leite auch nicht automatisch auf gescannte URLs weiter, sonst droht Phishing per präpariertem QR-Code. VerwendetextContentund prüfe URLs vorher. - Bilder von fremden Domains ohne CORS-Freigabe (tainted canvas) führen zu einem
SecurityError.