From 89c1c836fd79496f0e9259b280945ace5c988b1e Mon Sep 17 00:00:00 2001 From: Adarsh Jaiswal Date: Thu, 10 Sep 2026 04:23:03 +0530 Subject: [PATCH] feat(barcode-scanner): expose enableAllPotentialBarcodes 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`. --- docs/content/docs/barcode-scanner.mdx | 18 ++++++++++ ...cannerOptions+toMLBarcodeScannerOptions.kt | 24 ++++++++----- .../android/c++/JBarcodeScannerOptions.hpp | 11 ++++-- .../c++/JBarcodeScannerOutputOptions.hpp | 6 +++- .../c++/JHybridBarcodeScannerFactorySpec.cpp | 2 +- .../barcodescanner/BarcodeScannerOptions.kt | 13 ++++--- .../BarcodeScannerOutputOptions.kt | 13 ++++--- ...nCameraBarcodeScanner-Swift-Cxx-Bridge.hpp | 15 ++++++++ .../HybridBarcodeScannerFactorySpecSwift.hpp | 2 +- .../ios/swift/BarcodeScannerOptions.swift | 20 ++++++++++- .../swift/BarcodeScannerOutputOptions.swift | 20 ++++++++++- .../shared/c++/BarcodeScannerOptions.hpp | 9 +++-- .../c++/BarcodeScannerOutputOptions.hpp | 6 +++- .../src/specs/BarcodeScannerFactory.nitro.ts | 34 +++++++++++++++++++ 14 files changed, 166 insertions(+), 27 deletions(-) diff --git a/docs/content/docs/barcode-scanner.mdx b/docs/content/docs/barcode-scanner.mdx index 1287044049..ab0f71bac7 100644 --- a/docs/content/docs/barcode-scanner.mdx +++ b/docs/content/docs/barcode-scanner.mdx @@ -129,6 +129,24 @@ async function scanBarcodeImage() { The examples above are configured to detect **all** [`BarcodeFormat`](/api/react-native-vision-camera-barcode-scanner/type-aliases/BarcodeFormat)s. To improve performance, you should narrow [`barcodeFormats`](/api/react-native-vision-camera-barcode-scanner/interfaces/BarcodeScannerOptions#barcodeformats) down to only the formats you need - for example [`'code-128'`](/api/react-native-vision-camera-barcode-scanner/type-aliases/BarcodeFormat) - which is a common Barcode Format, or [`'qr-code'`](/api/react-native-vision-camera-barcode-scanner/type-aliases/BarcodeFormat) for square QR codes. +### Potential Barcodes + +By default only decoded Barcodes are returned, so a Barcode MLKit could not read looks the same as no Barcode at all. + +Enable [`enableAllPotentialBarcodes`](/api/react-native-vision-camera-barcode-scanner/interfaces/BarcodeScannerOptions#enableallpotentialbarcodes) to also receive those: + +```ts +const scanner = useBarcodeScanner({ + barcodeFormats: ['qr-code'], + enableAllPotentialBarcodes: true, +}) +``` + +On a potential [`Barcode`](/api/react-native-vision-camera-barcode-scanner/hybrid-objects/Barcode), [`rawValue`](/api/react-native-vision-camera-barcode-scanner/hybrid-objects/Barcode#rawvalue) is `undefined` and [`boundingBox`](/api/react-native-vision-camera-barcode-scanner/hybrid-objects/Barcode#boundingbox) describes where it is - use it to zoom towards a Barcode that is too small to decode. + +> [!NOTE] +> This option is Android-only. + ### Test it To verify your [``](/api/react-native-vision-camera-barcode-scanner/views/CodeScanner) works, try scanning this example [`'code-128'`](/api/react-native-vision-camera-barcode-scanner/type-aliases/BarcodeFormat) Barcode: diff --git a/packages/react-native-vision-camera-barcode-scanner/android/src/main/java/com/margelo/nitro/camera/barcodescanner/extensions/BarcodeScannerOptions+toMLBarcodeScannerOptions.kt b/packages/react-native-vision-camera-barcode-scanner/android/src/main/java/com/margelo/nitro/camera/barcodescanner/extensions/BarcodeScannerOptions+toMLBarcodeScannerOptions.kt index c5ca96d1d6..bc0e894ff9 100644 --- a/packages/react-native-vision-camera-barcode-scanner/android/src/main/java/com/margelo/nitro/camera/barcodescanner/extensions/BarcodeScannerOptions+toMLBarcodeScannerOptions.kt +++ b/packages/react-native-vision-camera-barcode-scanner/android/src/main/java/com/margelo/nitro/camera/barcodescanner/extensions/BarcodeScannerOptions+toMLBarcodeScannerOptions.kt @@ -16,15 +16,23 @@ private fun com.google.mlkit.vision.barcode.BarcodeScannerOptions.Builder.setBar } fun BarcodeScannerOptions.toMLBarcodeScannerOptions(): com.google.mlkit.vision.barcode.BarcodeScannerOptions { - return com.google.mlkit.vision.barcode.BarcodeScannerOptions - .Builder() - .setBarcodeFormats(this.barcodeFormats) - .build() + val builder = + com.google.mlkit.vision.barcode.BarcodeScannerOptions + .Builder() + .setBarcodeFormats(this.barcodeFormats) + if (this.enableAllPotentialBarcodes == true) { + builder.enableAllPotentialBarcodes() + } + return builder.build() } fun BarcodeScannerOutputOptions.toMLBarcodeScannerOptions(): com.google.mlkit.vision.barcode.BarcodeScannerOptions { - return com.google.mlkit.vision.barcode.BarcodeScannerOptions - .Builder() - .setBarcodeFormats(this.barcodeFormats) - .build() + val builder = + com.google.mlkit.vision.barcode.BarcodeScannerOptions + .Builder() + .setBarcodeFormats(this.barcodeFormats) + if (this.enableAllPotentialBarcodes == true) { + builder.enableAllPotentialBarcodes() + } + return builder.build() } diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JBarcodeScannerOptions.hpp b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JBarcodeScannerOptions.hpp index e392c42faf..5317ac8471 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JBarcodeScannerOptions.hpp +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JBarcodeScannerOptions.hpp @@ -12,6 +12,7 @@ #include "JTargetBarcodeFormat.hpp" #include "TargetBarcodeFormat.hpp" +#include #include namespace margelo::nitro::camera::barcodescanner { @@ -35,6 +36,8 @@ namespace margelo::nitro::camera::barcodescanner { static const auto clazz = javaClassStatic(); static const auto fieldBarcodeFormats = clazz->getField>("barcodeFormats"); jni::local_ref> barcodeFormats = this->getFieldValue(fieldBarcodeFormats); + static const auto fieldEnableAllPotentialBarcodes = clazz->getField("enableAllPotentialBarcodes"); + jni::local_ref enableAllPotentialBarcodes = this->getFieldValue(fieldEnableAllPotentialBarcodes); return BarcodeScannerOptions( [&](auto&& __input) { size_t __size = __input->size(); @@ -45,7 +48,8 @@ namespace margelo::nitro::camera::barcodescanner { __vector.push_back(__element->toCpp()); } return __vector; - }(barcodeFormats) + }(barcodeFormats), + enableAllPotentialBarcodes != nullptr ? std::make_optional(static_cast(enableAllPotentialBarcodes->value())) : std::nullopt ); } @@ -55,7 +59,7 @@ namespace margelo::nitro::camera::barcodescanner { */ [[maybe_unused]] static jni::local_ref fromCpp(const BarcodeScannerOptions& value) { - using JSignature = JBarcodeScannerOptions(jni::alias_ref>); + using JSignature = JBarcodeScannerOptions(jni::alias_ref>, jni::alias_ref); static const auto clazz = javaClassStatic(); static const auto create = clazz->getStaticMethod("fromCpp"); return create( @@ -69,7 +73,8 @@ namespace margelo::nitro::camera::barcodescanner { __array->setElement(__i, *__elementJni); } return __array; - }(value.barcodeFormats) + }(value.barcodeFormats), + value.enableAllPotentialBarcodes.has_value() ? jni::JBoolean::valueOf(value.enableAllPotentialBarcodes.value()) : nullptr ); } }; diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JBarcodeScannerOutputOptions.hpp b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JBarcodeScannerOutputOptions.hpp index 49b210560d..55d3aefceb 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JBarcodeScannerOutputOptions.hpp +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JBarcodeScannerOutputOptions.hpp @@ -48,6 +48,8 @@ namespace margelo::nitro::camera::barcodescanner { jni::local_ref> barcodeFormats = this->getFieldValue(fieldBarcodeFormats); static const auto fieldOutputResolution = clazz->getField("outputResolution"); jni::local_ref outputResolution = this->getFieldValue(fieldOutputResolution); + static const auto fieldEnableAllPotentialBarcodes = clazz->getField("enableAllPotentialBarcodes"); + jni::local_ref enableAllPotentialBarcodes = this->getFieldValue(fieldEnableAllPotentialBarcodes); static const auto fieldOnBarcodeScanned = clazz->getField("onBarcodeScanned"); jni::local_ref onBarcodeScanned = this->getFieldValue(fieldOnBarcodeScanned); static const auto fieldOnError = clazz->getField("onError"); @@ -64,6 +66,7 @@ namespace margelo::nitro::camera::barcodescanner { return __vector; }(barcodeFormats), outputResolution != nullptr ? std::make_optional(outputResolution->toCpp()) : std::nullopt, + enableAllPotentialBarcodes != nullptr ? std::make_optional(static_cast(enableAllPotentialBarcodes->value())) : std::nullopt, [&]() -> std::function>& /* barcodes */)> { if (onBarcodeScanned->isInstanceOf(JFunc_void_std__vector_std__shared_ptr_HybridBarcodeSpec___cxx::javaClassStatic())) [[likely]] { auto downcast = jni::static_ref_cast(onBarcodeScanned); @@ -91,7 +94,7 @@ namespace margelo::nitro::camera::barcodescanner { */ [[maybe_unused]] static jni::local_ref fromCpp(const BarcodeScannerOutputOptions& value) { - using JSignature = JBarcodeScannerOutputOptions(jni::alias_ref>, jni::alias_ref, jni::alias_ref, jni::alias_ref); + using JSignature = JBarcodeScannerOutputOptions(jni::alias_ref>, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref); static const auto clazz = javaClassStatic(); static const auto create = clazz->getStaticMethod("fromCpp"); return create( @@ -107,6 +110,7 @@ namespace margelo::nitro::camera::barcodescanner { return __array; }(value.barcodeFormats), value.outputResolution.has_value() ? JBarcodeScannerOutputResolution::fromCpp(value.outputResolution.value()) : nullptr, + value.enableAllPotentialBarcodes.has_value() ? jni::JBoolean::valueOf(value.enableAllPotentialBarcodes.value()) : nullptr, JFunc_void_std__vector_std__shared_ptr_HybridBarcodeSpec___cxx::fromCpp(value.onBarcodeScanned), JFunc_void_std__exception_ptr_cxx::fromCpp(value.onError) ); diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JHybridBarcodeScannerFactorySpec.cpp b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JHybridBarcodeScannerFactorySpec.cpp index 3a1983b97c..aa3818f793 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JHybridBarcodeScannerFactorySpec.cpp +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/c++/JHybridBarcodeScannerFactorySpec.cpp @@ -32,10 +32,10 @@ namespace margelo::nitro::camera::barcodescanner { class HybridBarcodeSpec; } #include "TargetBarcodeFormat.hpp" #include #include "JTargetBarcodeFormat.hpp" +#include #include "BarcodeScannerOutputOptions.hpp" #include "JBarcodeScannerOutputOptions.hpp" #include "BarcodeScannerOutputResolution.hpp" -#include #include "JBarcodeScannerOutputResolution.hpp" #include "HybridBarcodeSpec.hpp" #include diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/barcodescanner/BarcodeScannerOptions.kt b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/barcodescanner/BarcodeScannerOptions.kt index 45c6dfd99c..d3a44326aa 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/barcodescanner/BarcodeScannerOptions.kt +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/barcodescanner/BarcodeScannerOptions.kt @@ -20,7 +20,10 @@ import java.util.Objects data class BarcodeScannerOptions( @DoNotStrip @Keep - val barcodeFormats: Array + val barcodeFormats: Array, + @DoNotStrip + @Keep + val enableAllPotentialBarcodes: Boolean? ) { /* primary constructor */ @@ -28,11 +31,13 @@ data class BarcodeScannerOptions( if (this === other) return true if (other !is BarcodeScannerOptions) return false return Objects.deepEquals(this.barcodeFormats, other.barcodeFormats) + && Objects.deepEquals(this.enableAllPotentialBarcodes, other.enableAllPotentialBarcodes) } override fun hashCode(): Int { return arrayOf( - barcodeFormats + barcodeFormats, + enableAllPotentialBarcodes ).contentDeepHashCode() } @@ -44,8 +49,8 @@ data class BarcodeScannerOptions( @Keep @Suppress("unused") @JvmStatic - private fun fromCpp(barcodeFormats: Array): BarcodeScannerOptions { - return BarcodeScannerOptions(barcodeFormats) + private fun fromCpp(barcodeFormats: Array, enableAllPotentialBarcodes: Boolean?): BarcodeScannerOptions { + return BarcodeScannerOptions(barcodeFormats, enableAllPotentialBarcodes) } } } diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/barcodescanner/BarcodeScannerOutputOptions.kt b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/barcodescanner/BarcodeScannerOutputOptions.kt index eeb811bc6f..a8d04bbf48 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/barcodescanner/BarcodeScannerOutputOptions.kt +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/barcodescanner/BarcodeScannerOutputOptions.kt @@ -26,6 +26,9 @@ data class BarcodeScannerOutputOptions( val outputResolution: BarcodeScannerOutputResolution?, @DoNotStrip @Keep + val enableAllPotentialBarcodes: Boolean?, + @DoNotStrip + @Keep val onBarcodeScanned: Func_void_std__vector_std__shared_ptr_HybridBarcodeSpec__, @DoNotStrip @Keep @@ -34,14 +37,15 @@ data class BarcodeScannerOutputOptions( /** * Create a new instance of BarcodeScannerOutputOptions from Kotlin */ - constructor(barcodeFormats: Array, outputResolution: BarcodeScannerOutputResolution?, onBarcodeScanned: (barcodes: Array) -> Unit, onError: (error: Throwable) -> Unit): - this(barcodeFormats, outputResolution, Func_void_std__vector_std__shared_ptr_HybridBarcodeSpec___java(onBarcodeScanned), Func_void_std__exception_ptr_java(onError)) + constructor(barcodeFormats: Array, outputResolution: BarcodeScannerOutputResolution?, enableAllPotentialBarcodes: Boolean?, onBarcodeScanned: (barcodes: Array) -> Unit, onError: (error: Throwable) -> Unit): + this(barcodeFormats, outputResolution, enableAllPotentialBarcodes, Func_void_std__vector_std__shared_ptr_HybridBarcodeSpec___java(onBarcodeScanned), Func_void_std__exception_ptr_java(onError)) override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is BarcodeScannerOutputOptions) return false return Objects.deepEquals(this.barcodeFormats, other.barcodeFormats) && Objects.deepEquals(this.outputResolution, other.outputResolution) + && Objects.deepEquals(this.enableAllPotentialBarcodes, other.enableAllPotentialBarcodes) && Objects.deepEquals(this.onBarcodeScanned, other.onBarcodeScanned) && Objects.deepEquals(this.onError, other.onError) } @@ -50,6 +54,7 @@ data class BarcodeScannerOutputOptions( return arrayOf( barcodeFormats, outputResolution, + enableAllPotentialBarcodes, onBarcodeScanned, onError ).contentDeepHashCode() @@ -63,8 +68,8 @@ data class BarcodeScannerOutputOptions( @Keep @Suppress("unused") @JvmStatic - private fun fromCpp(barcodeFormats: Array, outputResolution: BarcodeScannerOutputResolution?, onBarcodeScanned: Func_void_std__vector_std__shared_ptr_HybridBarcodeSpec__, onError: Func_void_std__exception_ptr): BarcodeScannerOutputOptions { - return BarcodeScannerOutputOptions(barcodeFormats, outputResolution, onBarcodeScanned, onError) + private fun fromCpp(barcodeFormats: Array, outputResolution: BarcodeScannerOutputResolution?, enableAllPotentialBarcodes: Boolean?, onBarcodeScanned: Func_void_std__vector_std__shared_ptr_HybridBarcodeSpec__, onError: Func_void_std__exception_ptr): BarcodeScannerOutputOptions { + return BarcodeScannerOutputOptions(barcodeFormats, outputResolution, enableAllPotentialBarcodes, onBarcodeScanned, onError) } } } diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/VisionCameraBarcodeScanner-Swift-Cxx-Bridge.hpp b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/VisionCameraBarcodeScanner-Swift-Cxx-Bridge.hpp index 6e5b168c8e..df8e7396db 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/VisionCameraBarcodeScanner-Swift-Cxx-Bridge.hpp +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/VisionCameraBarcodeScanner-Swift-Cxx-Bridge.hpp @@ -256,6 +256,21 @@ namespace margelo::nitro::camera::barcodescanner::bridge::swift { return vector; } + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_bool_ = std::optional; + inline std::optional create_std__optional_bool_(const bool& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_bool_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline bool get_std__optional_bool_(const std::optional& optional) noexcept { + return optional.value(); + } + // pragma MARK: std::shared_ptr /** * Specialized version of `std::shared_ptr`. diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/c++/HybridBarcodeScannerFactorySpecSwift.hpp b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/c++/HybridBarcodeScannerFactorySpecSwift.hpp index a1b4397f2e..f395521c67 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/c++/HybridBarcodeScannerFactorySpecSwift.hpp +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/c++/HybridBarcodeScannerFactorySpecSwift.hpp @@ -32,10 +32,10 @@ namespace margelo::nitro::camera::barcodescanner { class HybridBarcodeSpec; } #include "BarcodeScannerOptions.hpp" #include "TargetBarcodeFormat.hpp" #include +#include #include #include "BarcodeScannerOutputOptions.hpp" #include "BarcodeScannerOutputResolution.hpp" -#include #include "HybridBarcodeSpec.hpp" #include #include diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/swift/BarcodeScannerOptions.swift b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/swift/BarcodeScannerOptions.swift index 0f92ab0680..89121c6c25 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/swift/BarcodeScannerOptions.swift +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/swift/BarcodeScannerOptions.swift @@ -18,13 +18,19 @@ public extension BarcodeScannerOptions { /** * Create a new instance of `BarcodeScannerOptions`. */ - init(barcodeFormats: [TargetBarcodeFormat]) { + init(barcodeFormats: [TargetBarcodeFormat], enableAllPotentialBarcodes: Bool?) { self.init({ () -> bridge.std__vector_TargetBarcodeFormat_ in var __vector = bridge.create_std__vector_TargetBarcodeFormat_(barcodeFormats.count) for __item in barcodeFormats { __vector.push_back(__item) } return __vector + }(), { () -> bridge.std__optional_bool_ in + if let __unwrappedValue = enableAllPotentialBarcodes { + return bridge.create_std__optional_bool_(__unwrappedValue) + } else { + return .init() + } }()) } @@ -32,4 +38,16 @@ public extension BarcodeScannerOptions { var barcodeFormats: [TargetBarcodeFormat] { return self.__barcodeFormats.map({ __item in __item }) } + + @inline(__always) + var enableAllPotentialBarcodes: Bool? { + return { () -> Bool? in + if bridge.has_value_std__optional_bool_(self.__enableAllPotentialBarcodes) { + let __unwrapped = bridge.get_std__optional_bool_(self.__enableAllPotentialBarcodes) + return __unwrapped + } else { + return nil + } + }() + } } diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/swift/BarcodeScannerOutputOptions.swift b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/swift/BarcodeScannerOutputOptions.swift index d340323790..4772ce8379 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/swift/BarcodeScannerOutputOptions.swift +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/ios/swift/BarcodeScannerOutputOptions.swift @@ -18,7 +18,7 @@ public extension BarcodeScannerOutputOptions { /** * Create a new instance of `BarcodeScannerOutputOptions`. */ - init(barcodeFormats: [TargetBarcodeFormat], outputResolution: BarcodeScannerOutputResolution?, onBarcodeScanned: @escaping (_ barcodes: [(any HybridBarcodeSpec)]) -> Void, onError: @escaping (_ error: Error) -> Void) { + init(barcodeFormats: [TargetBarcodeFormat], outputResolution: BarcodeScannerOutputResolution?, enableAllPotentialBarcodes: Bool?, onBarcodeScanned: @escaping (_ barcodes: [(any HybridBarcodeSpec)]) -> Void, onError: @escaping (_ error: Error) -> Void) { self.init({ () -> bridge.std__vector_TargetBarcodeFormat_ in var __vector = bridge.create_std__vector_TargetBarcodeFormat_(barcodeFormats.count) for __item in barcodeFormats { @@ -31,6 +31,12 @@ public extension BarcodeScannerOutputOptions { } else { return .init() } + }(), { () -> bridge.std__optional_bool_ in + if let __unwrappedValue = enableAllPotentialBarcodes { + return bridge.create_std__optional_bool_(__unwrappedValue) + } else { + return .init() + } }(), { () -> bridge.Func_void_std__vector_std__shared_ptr_HybridBarcodeSpec__ in let __closureWrapper = Func_void_std__vector_std__shared_ptr_HybridBarcodeSpec__(onBarcodeScanned) return bridge.create_Func_void_std__vector_std__shared_ptr_HybridBarcodeSpec__(__closureWrapper.toUnsafe()) @@ -50,6 +56,18 @@ public extension BarcodeScannerOutputOptions { return self.__outputResolution.value } + @inline(__always) + var enableAllPotentialBarcodes: Bool? { + return { () -> Bool? in + if bridge.has_value_std__optional_bool_(self.__enableAllPotentialBarcodes) { + let __unwrapped = bridge.get_std__optional_bool_(self.__enableAllPotentialBarcodes) + return __unwrapped + } else { + return nil + } + }() + } + @inline(__always) var onBarcodeScanned: (_ barcodes: [(any HybridBarcodeSpec)]) -> Void { return { () -> ([(any HybridBarcodeSpec)]) -> Void in diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp index 2b3ae70b9c..031f4b9efc 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp @@ -33,6 +33,7 @@ namespace margelo::nitro::camera::barcodescanner { enum class TargetBarcodeForma #include "TargetBarcodeFormat.hpp" #include +#include namespace margelo::nitro::camera::barcodescanner { @@ -42,10 +43,11 @@ namespace margelo::nitro::camera::barcodescanner { struct BarcodeScannerOptions final { public: std::vector barcodeFormats SWIFT_PRIVATE; + std::optional enableAllPotentialBarcodes SWIFT_PRIVATE; public: BarcodeScannerOptions() = default; - explicit BarcodeScannerOptions(std::vector barcodeFormats): barcodeFormats(barcodeFormats) {} + explicit BarcodeScannerOptions(std::vector barcodeFormats, std::optional enableAllPotentialBarcodes): barcodeFormats(barcodeFormats), enableAllPotentialBarcodes(enableAllPotentialBarcodes) {} public: friend bool operator==(const BarcodeScannerOptions& lhs, const BarcodeScannerOptions& rhs) = default; @@ -61,12 +63,14 @@ namespace margelo::nitro { static inline margelo::nitro::camera::barcodescanner::BarcodeScannerOptions fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { jsi::Object obj = arg.asObject(runtime); return margelo::nitro::camera::barcodescanner::BarcodeScannerOptions( - JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "barcodeFormats"))) + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "barcodeFormats"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes"))) ); } static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::camera::barcodescanner::BarcodeScannerOptions& arg) { jsi::Object obj(runtime); obj.setProperty(runtime, PropNameIDCache::get(runtime, "barcodeFormats"), JSIConverter>::toJSI(runtime, arg.barcodeFormats)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes"), JSIConverter>::toJSI(runtime, arg.enableAllPotentialBarcodes)); return obj; } static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { @@ -78,6 +82,7 @@ namespace margelo::nitro { return false; } if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "barcodeFormats")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes")))) return false; return true; } }; diff --git a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/shared/c++/BarcodeScannerOutputOptions.hpp b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/shared/c++/BarcodeScannerOutputOptions.hpp index b0604e0db4..eeb7c20288 100644 --- a/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/shared/c++/BarcodeScannerOutputOptions.hpp +++ b/packages/react-native-vision-camera-barcode-scanner/nitrogen/generated/shared/c++/BarcodeScannerOutputOptions.hpp @@ -53,12 +53,13 @@ namespace margelo::nitro::camera::barcodescanner { public: std::vector barcodeFormats SWIFT_PRIVATE; std::optional outputResolution SWIFT_PRIVATE; + std::optional enableAllPotentialBarcodes SWIFT_PRIVATE; std::function>& /* barcodes */)> onBarcodeScanned SWIFT_PRIVATE; std::function onError SWIFT_PRIVATE; public: BarcodeScannerOutputOptions() = default; - explicit BarcodeScannerOutputOptions(std::vector barcodeFormats, std::optional outputResolution, std::function>& /* barcodes */)> onBarcodeScanned, std::function onError): barcodeFormats(barcodeFormats), outputResolution(outputResolution), onBarcodeScanned(onBarcodeScanned), onError(onError) {} + explicit BarcodeScannerOutputOptions(std::vector barcodeFormats, std::optional outputResolution, std::optional enableAllPotentialBarcodes, std::function>& /* barcodes */)> onBarcodeScanned, std::function onError): barcodeFormats(barcodeFormats), outputResolution(outputResolution), enableAllPotentialBarcodes(enableAllPotentialBarcodes), onBarcodeScanned(onBarcodeScanned), onError(onError) {} public: // BarcodeScannerOutputOptions is not equatable because these properties are not equatable: onBarcodeScanned, onError @@ -76,6 +77,7 @@ namespace margelo::nitro { return margelo::nitro::camera::barcodescanner::BarcodeScannerOutputOptions( JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "barcodeFormats"))), JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "outputResolution"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes"))), JSIConverter>&)>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "onBarcodeScanned"))), JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "onError"))) ); @@ -84,6 +86,7 @@ namespace margelo::nitro { jsi::Object obj(runtime); obj.setProperty(runtime, PropNameIDCache::get(runtime, "barcodeFormats"), JSIConverter>::toJSI(runtime, arg.barcodeFormats)); obj.setProperty(runtime, PropNameIDCache::get(runtime, "outputResolution"), JSIConverter>::toJSI(runtime, arg.outputResolution)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes"), JSIConverter>::toJSI(runtime, arg.enableAllPotentialBarcodes)); obj.setProperty(runtime, PropNameIDCache::get(runtime, "onBarcodeScanned"), JSIConverter>&)>>::toJSI(runtime, arg.onBarcodeScanned)); obj.setProperty(runtime, PropNameIDCache::get(runtime, "onError"), JSIConverter>::toJSI(runtime, arg.onError)); return obj; @@ -98,6 +101,7 @@ namespace margelo::nitro { } if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "barcodeFormats")))) return false; if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "outputResolution")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes")))) return false; if (!JSIConverter>&)>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "onBarcodeScanned")))) return false; if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "onError")))) return false; return true; diff --git a/packages/react-native-vision-camera-barcode-scanner/src/specs/BarcodeScannerFactory.nitro.ts b/packages/react-native-vision-camera-barcode-scanner/src/specs/BarcodeScannerFactory.nitro.ts index 00e2519ce8..5a4d67b856 100644 --- a/packages/react-native-vision-camera-barcode-scanner/src/specs/BarcodeScannerFactory.nitro.ts +++ b/packages/react-native-vision-camera-barcode-scanner/src/specs/BarcodeScannerFactory.nitro.ts @@ -14,6 +14,23 @@ export interface BarcodeScannerOptions { * use {@linkcode TargetBarcodeFormat | ['all-formats']} */ barcodeFormats: TargetBarcodeFormat[] + /** + * Also return Barcodes that were located, but could not be decoded. + * + * On such a {@linkcode Barcode}, {@linkcode Barcode.rawValue | rawValue} + * and {@linkcode Barcode.rawBytes | rawBytes} are `undefined`, while + * {@linkcode Barcode.boundingBox | boundingBox} describes the region that + * potentially contains a Barcode. + * + * This distinguishes "no Barcode is in view" from "a Barcode is in view + * that cannot be read" — two failures with opposite fixes (lighting and + * contrast vs. zoom and distance). It can also drive the camera's zoom: + * a code too small to decode still reports where it is. + * + * @note Android only — the iOS MLKit SDK exposes no equivalent option. + * @default false + */ + enableAllPotentialBarcodes?: boolean } export interface BarcodeScannerOutputOptions { @@ -34,6 +51,23 @@ export interface BarcodeScannerOutputOptions { * @default 'preview' */ outputResolution?: BarcodeScannerOutputResolution + /** + * Also return Barcodes that were located, but could not be decoded. + * + * On such a {@linkcode Barcode}, {@linkcode Barcode.rawValue | rawValue} + * and {@linkcode Barcode.rawBytes | rawBytes} are `undefined`, while + * {@linkcode Barcode.boundingBox | boundingBox} describes the region that + * potentially contains a Barcode. + * + * This distinguishes "no Barcode is in view" from "a Barcode is in view + * that cannot be read" — two failures with opposite fixes (lighting and + * contrast vs. zoom and distance). It can also drive the camera's zoom: + * a code too small to decode still reports where it is. + * + * @note Android only — the iOS MLKit SDK exposes no equivalent option. + * @default false + */ + enableAllPotentialBarcodes?: boolean /** * Called whenever barcodes have been detected. */