feat(barcode-scanner): expose enableAllPotentialBarcodes - #4188
feat(barcode-scanner): expose enableAllPotentialBarcodes#4188AdarshJais wants to merge 1 commit into
Conversation
|
@AdarshJais is attempting to deploy a commit to the Margelo Team on Vercel. A member of the Team first needs to authorize it. |
|
@mrousavy, could you or any of the reviewers (not sure who all are involved) please take some time to look into this PR and share your feedback? It would be really valuable. |
| ### Barcodes that cannot be decoded | ||
|
|
||
| By default, only successfully decoded Barcodes are returned. A frame containing a | ||
| Barcode that MLKit could not read is indistinguishable from a frame containing no | ||
| Barcode at all - both give you an empty array. | ||
|
|
||
| Enable [`enableAllPotentialBarcodes`](/api/react-native-vision-camera-barcode-scanner/interfaces/BarcodeScannerOptions#enableallpotentialbarcodes) | ||
| to also receive the ones it located but could not read: | ||
|
|
||
| ```ts | ||
| const scanner = useBarcodeScanner({ | ||
| barcodeFormats: ['qr-code'], | ||
| enableAllPotentialBarcodes: true, | ||
| }) | ||
| ``` | ||
|
|
||
| On those Barcodes, [`rawValue`](/api/react-native-vision-camera-barcode-scanner/hybrid-objects/Barcode#rawvalue) | ||
| is `undefined` while [`boundingBox`](/api/react-native-vision-camera-barcode-scanner/hybrid-objects/Barcode#boundingbox) | ||
| describes where the potential Barcode is. That tells apart two failures which need | ||
| opposite fixes - a Barcode that cannot be *seen* (lighting, contrast, focus) from one | ||
| that cannot be *read* (too far away, or too few pixels per module) - and lets you act | ||
| on the second by zooming towards the reported region. | ||
|
|
||
| > [!NOTE] | ||
| > This is an Android-only option. The iOS MLKit SDK exposes no equivalent, and setting | ||
| > it there has no effect. | ||
|
|
There was a problem hiding this comment.
This AI-generated docs section is bad. It will have to be re-written.
As for iOS support, why doesn't MLKit provide that?
There was a problem hiding this comment.
Fair, rewrote it, was way too wordy for the rest of the page.
On iOS: MLKit doesn't expose it there. The iOS BarcodeScannerOptions is only formats no enableAllPotentialBarcodes, and no setZoomSuggestionOptions either, so the iOS SDK looks generally behind on options rather than this being a deliberate omission. Couldn't find anything from Google explaining why
Lemme know, If I might be missing any direction here.
MLKit can return Barcodes it located but could not decode, with rawValue undefined and boundingBox describing the region. That option was not reachable from JS, so a Barcode that cannot be read is indistinguishable from no Barcode at all - both return an empty array. Those are two different failures with opposite fixes: a Barcode that cannot be seen (lighting, contrast, focus) versus one that cannot be read (too far away, too few pixels per module). Surfacing the located-but- undecoded ones separates them, and their boundingBox can drive zoom. Android only - the iOS MLKit SDK exposes no equivalent option. Documented as Android-only in the spec, matching CameraExtension and CameraDevice.supportsFocus. Defaults to false, so behaviour is unchanged for existing users. Requires bundled model 17.1.0+; the package already ships 17.3.0. Generated Nitro files updated with `bun scanner specs`.
8efc807 to
89c1c83
Compare
The gap
From JS there is currently no way to tell whether the camera is looking at something barcode-shaped at all. A frame with no Barcode and a frame containing a Barcode that MLKit could not read both return an empty array.
That makes scan failures unmeasurable. When a user reports "it just doesn't scan", there is nothing to inspect — you cannot distinguish:
Those need opposite corrections. More light versus more zoom. Without the distinction, any fix is a guess.
MLKit already provides this — it just isn't reachable
From Google's Android barcode-scanning guide:
And from the
BarcodeScannerOptions.Builderreference:The package already ships MLKit
17.3.0, so the capability is present.toMLBarcodeScannerOptions()just buildsBarcodeScannerOptions.Builder().setBarcodeFormats(...).build()and nothing else, so it cannot be turned on.API
const scanner = useBarcodeScanner({ barcodeFormats: ['qr-code'], enableAllPotentialBarcodes: true, })Also available on
useBarcodeScannerOutput/<CodeScanner />.What it enables
Two things that are impossible today:
margelo/react-native-vision-camera#3957 and margelo/react-native-vision-camera#4142 both report "the scanner misses barcodes that are clearly visible on screen", and both were closed for lack of a reproduction. This flag is what would let a reporter produce one.
Verified against a real failing label
A QR printed directly onto kraft paper (common low-contrast delivery packaging), at 1280×720 / ~30fps:
Before this flag that session produced no signal whatsoever. With it, the 13% detection rate says the problem is detection, not decoding — which points at contrast and focus rather than zoom, and would have led to the wrong fix without it.
Also verified on a deliberately masked QR: located continuously, decoded only once uncovered.
Platform support
Android only.
MLKitBarcodeScanning.BarcodeScannerOptionson iOS exposes onlyformats— there is no equivalent. Documented with@note, matching the existing pattern onCameraExtension("only supported on Android") andCameraDevice.supportsFocus("On non iOS platforms this is alwaysfalse").Notes
false— no behaviour change for existing users.bun scanner specs; the diff is purely additive (std::optional<bool>/Boolean?).bun lint-kotlinand Biome both clean.barcode-scanner.mdx.Follow-up (not in this PR)
The gapsetZoomSuggestionOptionsis the natural companion — it consumes these bounding boxes to auto-zoom. Kept separate to keep this reviewable.