直接传 <img> 给 detect() 会失败,因为 BarcodeDetector.detect() 仅接受 ImageBitmap、HTMLCanvasElement、OffscreenCanvas 或 VideoFrame 四类图像源;<img> 元素本身不可绘制,且需满足 complete、跨域设置、尺寸精度等硬性条件。
<img> 给 detect() 会失败因为 BarcodeDetector.detect() 只接受四类图像源:ImageBitmap、HTMLCanvasElement、OffscreenCanvas 或 VideoFrame。DOM 中的 <img> 元素本身不是可绘制图像源,传进去会静默失败或抛 NotAllowedError。
常见错误现象:调用后 Promise 一直 pending、控制台无报错但结果为空数组、detector.detect(img) 直接报类型错误。
img.complete === true 才能继续,否则 drawImage 画不出内容img.crossOrigin = 'anonymous',否则 canvas 被污染,后续 transferToImageBitmap() 报错img.naturalWidth / img.naturalHeight,拉伸或缩放会降低识别率ImageBitmap 两种生成方式怎么选canvas.transferToImageBitmap() 是推荐方式,性能更好、内存更可控;createImageBitmap(canvas) 兼容性略高(支持到 Chrome 52+),但可能触发额外解码开销。
实际差异主要在移动端:Android Chrome 90+ 支持 transferToImageBitmap,旧 WebView 则可能 fallback 到 createImageBitmap。
立即学习“前端免费学习笔记(深入)”;
canvas.transferToImageBitmap(),它把 canvas 内存直接移交,不复制像素数据createImageBitmap(canvas)
createImageBitmap(img) 直接转 DOM 图片——它仍受跨域限制,且不保证尺寸精度返回空数组 ≠ API 坏了,大概率是输入不符合最低质量门槛。Barcode Detection API 不做图像增强,纯靠原始像素匹配。
调试技巧:用 canvas.toDataURL('image/png') 截一帧保存下来,肉眼确认条码是否清晰、居中、无畸变。
构造 BarcodeDetector 实例时,formats 数组不能为空,且每个值必须是规范字符串——比如二维码必须写 "qr_code",不是 "qrcode"、"QR_CODE" 或 "qr"。
错误示例:new BarcodeDetector({ formats: ['QR_CODE'] }) 会直接抛 TypeError: format list must not be empty(即使数组非空,值非法也会被当空处理)。
detector.getSupportedFormats() 返回为准,Chrome 103+ 支持 ["qr_code", "ean_13", "code_128", "upc_a", "itf", "codabar"] 等["qr_code"]
真正容易被忽略的是:这个 API 在 Safari 和 Firefox 中永远不可用,'BarcodeDetector' in window 永远返回 false,别试图 polyfill 或强制启用。