Deux façons de décoder dans le navigateur
Côté web, lire un QR code ou un code-barres se fait aujourd’hui par deux chemins : l’API native BarcodeDetector, intégrée au navigateur, et ZXing, le port JavaScript de la bibliothèque de décodage open source. FlashScan Pro utilise les deux — cet article explique pourquoi, et comment.
BarcodeDetector : le chemin natif
BarcodeDetector fait partie de la « Shape Detection API » : le navigateur expose directement ses capacités de décodage, souvent implémentées au-dessus des bibliothèques système. Usage typique :
const detector = new BarcodeDetector({ formats: ['qr_code', 'ean_13', 'code_128'] })
const codes = await detector.detect(videoElement) // ou un ImageBitmap
Trois avantages décisifs : aucune dépendance à charger, un décodage optimisé par la plateforme (souvent en dehors du thread principal), et une API minimaliste — detect() prend un canvas, une vidéo ou un bitmap et renvoie les codes trouvés. La méthode statique BarcodeDetector.getSupportedFormats() liste les formats réellement gérés par le navigateur courant — indispensable, car la liste varie selon les plateformes.
Le problème : le support navigateurs
L’API est disponible dans la famille Chromium — Chrome, Edge, Opera, Chrome Android et WebView Android. Firefox ne l’implémente pas, Safari ne l’active pas par défaut. Pour une application grand public, ignorer ces navigateurs n’est pas une option : il faut un plan B.
ZXing : le décodeur universel
ZXing est le port JavaScript de la bibliothèque de décodage qui équipe une grande partie des applications Android depuis des années. Il travaille en pur software : les pixels de l’image ou de la vidéo sont convertis en luminance, binarisés, puis analysés par un MultiFormatReader. Dans FlashScan Pro, le fallback ZXing est configuré avec 11 formats — QR Code, Data Matrix, Aztec, PDF417, Code 128, Code 39, EAN-13, EAN-8, UPC-A, UPC-E et ITF — plus le hint TRY_HARDER qui force une analyse plus approfondie des images difficiles.
Le coût : une bibliothèque à télécharger et un décodage plus lent. D’où l’importance de ne la charger que si nécessaire.
La stratégie de fallback en pratique
L’architecture de l’app illustre le pattern recommandé :
- Détection de capacité : si
globalThis.BarcodeDetectorexiste, on l’instancie avec les formats utiles (qr_code,ean_13,ean_8,code_128,data_matrix). - Sinon, import dynamique :
await import('./zxingDecoder')charge ZXing à la demande — les utilisateurs Chromium ne paient jamais le coût du téléchargement. - Cadence adaptée : le scan caméra interroge le détecteur natif toutes les 120 ms, et ZXing toutes les 250 ms — le fallback logiciel étant plus coûteux, on lui laisse plus de temps entre deux frames.
- Même pattern pour les images :
detect()sur unImageBitmapsi l’API existe, sinon décodage ZXing des pixels de l’image importée.
Le point de vigilance : un code lu par le fallback peut couvrir des formats que la config native ne demande pas (UPC-E, ITF, Aztec…). Si votre application cible des formats précis, harmonisez les listes — un utilisateur Firefox ne devrait pas pouvoir scanner un format refusé sous Chrome.
Que choisir ?
- Application interne ou kiosk maîtrisé (Chrome garanti) : BarcodeDetector seul suffit.
- Application publique : BarcodeDetector en chemin rapide, ZXing en fallback lazy — c’est le compromis performance/couverture qui équipe le scanner de cette app.
- Décodage côté serveur ou hors navigateur : ni l’un ni l’autre n’est fait pour — ZXing Java ou une librairie native conviendront mieux.