Committed by
GitHub
Merge pull request #1202 from navaronbracke/always_return_capture_size
feat: Always return capture size
Showing
9 changed files
with
42 additions
and
41 deletions
| @@ -5,11 +5,14 @@ Improvements: | @@ -5,11 +5,14 @@ Improvements: | ||
| 5 | * [MacOS] Added support for `analyzeImage`. | 5 | * [MacOS] Added support for `analyzeImage`. |
| 6 | * [MacOS] Added a Privacy Manifest. | 6 | * [MacOS] Added a Privacy Manifest. |
| 7 | * [web] Added the size information to barcode results. | 7 | * [web] Added the size information to barcode results. |
| 8 | +* [web] Added the video output size information to barcode capture. | ||
| 8 | * Added support for barcode formats to image analysis. | 9 | * Added support for barcode formats to image analysis. |
| 9 | * Updated the scanner to report any scanning errors that were encountered during processing. | 10 | * Updated the scanner to report any scanning errors that were encountered during processing. |
| 10 | * Introduced a new getter `hasCameraPermission` for the `MobileScannerState`. | 11 | * Introduced a new getter `hasCameraPermission` for the `MobileScannerState`. |
| 11 | * Fixed a bug in the lifecycle handling sample. Now instead of checking `isInitialized`, | 12 | * Fixed a bug in the lifecycle handling sample. Now instead of checking `isInitialized`, |
| 12 | the sample recommends using `hasCameraPermission`, which also guards against camera permission errors. | 13 | the sample recommends using `hasCameraPermission`, which also guards against camera permission errors. |
| 14 | +* Updated the behavior of `returnImage` to only determine if the camera output bytes should be sent. | ||
| 15 | +* Updated the behavior of `BarcodeCapture.size` to always be provided when available, regardless of `returnImage`. | ||
| 13 | 16 | ||
| 14 | Bugs fixed: | 17 | Bugs fixed: |
| 15 | * Fixed a bug that would cause the scanner to emit an error when it was already started. Now it ignores any calls to start while it is starting. | 18 | * Fixed a bug that would cause the scanner to emit an error when it was already started. Now it ignores any calls to start while it is starting. |
| @@ -120,7 +120,11 @@ class MobileScanner( | @@ -120,7 +120,11 @@ class MobileScanner( | ||
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | if (!returnImage) { | 122 | if (!returnImage) { |
| 123 | - mobileScannerCallback(barcodeMap, null, null, null) | 123 | + mobileScannerCallback( |
| 124 | + barcodeMap, | ||
| 125 | + null, | ||
| 126 | + mediaImage.width, | ||
| 127 | + mediaImage.height) | ||
| 124 | return@addOnSuccessListener | 128 | return@addOnSuccessListener |
| 125 | } | 129 | } |
| 126 | 130 |
| @@ -47,22 +47,17 @@ class MobileScannerHandler( | @@ -47,22 +47,17 @@ class MobileScannerHandler( | ||
| 47 | private var analyzerResult: MethodChannel.Result? = null | 47 | private var analyzerResult: MethodChannel.Result? = null |
| 48 | 48 | ||
| 49 | private val callback: MobileScannerCallback = { barcodes: List<Map<String, Any?>>, image: ByteArray?, width: Int?, height: Int? -> | 49 | private val callback: MobileScannerCallback = { barcodes: List<Map<String, Any?>>, image: ByteArray?, width: Int?, height: Int? -> |
| 50 | - if (image != null) { | ||
| 51 | - barcodeHandler.publishEvent(mapOf( | ||
| 52 | - "name" to "barcode", | ||
| 53 | - "data" to barcodes, | ||
| 54 | - "image" to mapOf( | ||
| 55 | - "bytes" to image, | ||
| 56 | - "width" to width?.toDouble(), | ||
| 57 | - "height" to height?.toDouble(), | ||
| 58 | - ) | ||
| 59 | - )) | ||
| 60 | - } else { | ||
| 61 | - barcodeHandler.publishEvent(mapOf( | ||
| 62 | - "name" to "barcode", | ||
| 63 | - "data" to barcodes | ||
| 64 | - )) | ||
| 65 | - } | 50 | + barcodeHandler.publishEvent(mapOf( |
| 51 | + "name" to "barcode", | ||
| 52 | + "data" to barcodes, | ||
| 53 | + // The image dimensions are always provided. | ||
| 54 | + // The image bytes are only non-null when `returnImage` is true. | ||
| 55 | + "image" to mapOf( | ||
| 56 | + "bytes" to image, | ||
| 57 | + "width" to width?.toDouble(), | ||
| 58 | + "height" to height?.toDouble(), | ||
| 59 | + ) | ||
| 60 | + )) | ||
| 66 | } | 61 | } |
| 67 | 62 | ||
| 68 | private val errorCallback: MobileScannerErrorCallback = {error: String -> | 63 | private val errorCallback: MobileScannerErrorCallback = {error: String -> |
| @@ -69,22 +69,18 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin { | @@ -69,22 +69,18 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin { | ||
| 69 | return | 69 | return |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | - if (!MobileScannerPlugin.returnImage) { | ||
| 73 | - barcodeHandler.publishEvent([ | ||
| 74 | - "name": "barcode", | ||
| 75 | - "data": barcodesMap, | ||
| 76 | - ]) | ||
| 77 | - return | ||
| 78 | - } | 72 | + // The image dimensions are always provided. |
| 73 | + // The image bytes are only non-null when `returnImage` is true. | ||
| 74 | + let imageData: [String: Any?] = [ | ||
| 75 | + "bytes": MobileScannerPlugin.returnImage ? FlutterStandardTypedData(bytes: image.jpegData(compressionQuality: 0.8)!) : nil, | ||
| 76 | + "width": image.size.width, | ||
| 77 | + "height": image.size.height, | ||
| 78 | + ] | ||
| 79 | 79 | ||
| 80 | barcodeHandler.publishEvent([ | 80 | barcodeHandler.publishEvent([ |
| 81 | "name": "barcode", | 81 | "name": "barcode", |
| 82 | "data": barcodesMap, | 82 | "data": barcodesMap, |
| 83 | - "image": [ | ||
| 84 | - "bytes": FlutterStandardTypedData(bytes: image.jpegData(compressionQuality: 0.8)!), | ||
| 85 | - "width": image.size.width, | ||
| 86 | - "height": image.size.height, | ||
| 87 | - ], | 83 | + "image": imageData, |
| 88 | ]) | 84 | ]) |
| 89 | }, torchModeChangeCallback: { torchState in | 85 | }, torchModeChangeCallback: { torchState in |
| 90 | barcodeHandler.publishEvent(["name": "torchState", "data": torchState]) | 86 | barcodeHandler.publishEvent(["name": "torchState", "data": torchState]) |
| @@ -75,8 +75,7 @@ class MobileScannerController extends ValueNotifier<MobileScannerState> { | @@ -75,8 +75,7 @@ class MobileScannerController extends ValueNotifier<MobileScannerState> { | ||
| 75 | /// If this is empty, all supported formats are detected. | 75 | /// If this is empty, all supported formats are detected. |
| 76 | final List<BarcodeFormat> formats; | 76 | final List<BarcodeFormat> formats; |
| 77 | 77 | ||
| 78 | - /// Whether scanned barcodes should contain the image | ||
| 79 | - /// that is embedded into the barcode. | 78 | + /// Whether the [BarcodeCapture.image] bytes should be provided. |
| 80 | /// | 79 | /// |
| 81 | /// If this is false, [BarcodeCapture.image] will always be null. | 80 | /// If this is false, [BarcodeCapture.image] will always be null. |
| 82 | /// | 81 | /// |
| @@ -32,8 +32,6 @@ class BarcodeCapture { | @@ -32,8 +32,6 @@ class BarcodeCapture { | ||
| 32 | /// This is the data that was used to detect the available [barcodes], the input [image] and the [size]. | 32 | /// This is the data that was used to detect the available [barcodes], the input [image] and the [size]. |
| 33 | final Object? raw; | 33 | final Object? raw; |
| 34 | 34 | ||
| 35 | - /// The size of the input [image]. | ||
| 36 | - /// | ||
| 37 | - /// If [image] is null, this will be [Size.zero]. | 35 | + /// The size of the camera input [image]. |
| 38 | final Size size; | 36 | final Size size; |
| 39 | } | 37 | } |
| @@ -143,6 +143,7 @@ class MobileScannerWeb extends MobileScannerPlatform { | @@ -143,6 +143,7 @@ class MobileScannerWeb extends MobileScannerPlatform { | ||
| 143 | final JSArray<JSString>? facingModes = capabilities.facingModeNullable; | 143 | final JSArray<JSString>? facingModes = capabilities.facingModeNullable; |
| 144 | 144 | ||
| 145 | // TODO: this is an empty array on MacOS Chrome, where there is no facing mode, but one, user facing camera. | 145 | // TODO: this is an empty array on MacOS Chrome, where there is no facing mode, but one, user facing camera. |
| 146 | + // We might be able to add a workaround, using the label of the video track. | ||
| 146 | // Facing mode is not supported by this track, do nothing. | 147 | // Facing mode is not supported by this track, do nothing. |
| 147 | if (facingModes == null || facingModes.toDart.isEmpty) { | 148 | if (facingModes == null || facingModes.toDart.isEmpty) { |
| 148 | return; | 149 | return; |
| @@ -121,6 +121,7 @@ final class ZXingBarcodeReader extends BarcodeReader { | @@ -121,6 +121,7 @@ final class ZXingBarcodeReader extends BarcodeReader { | ||
| 121 | controller.add( | 121 | controller.add( |
| 122 | BarcodeCapture( | 122 | BarcodeCapture( |
| 123 | barcodes: [result.toBarcode], | 123 | barcodes: [result.toBarcode], |
| 124 | + size: videoSize, | ||
| 124 | ), | 125 | ), |
| 125 | ); | 126 | ); |
| 126 | } | 127 | } |
| @@ -156,22 +156,26 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -156,22 +156,26 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 156 | }) | 156 | }) |
| 157 | 157 | ||
| 158 | DispatchQueue.main.async { | 158 | DispatchQueue.main.async { |
| 159 | - if (!MobileScannerPlugin.returnImage) { | 159 | + guard let image = cgImage else { |
| 160 | self?.sink?([ | 160 | self?.sink?([ |
| 161 | "name": "barcode", | 161 | "name": "barcode", |
| 162 | "data": barcodes.map({ $0.toMap() }), | 162 | "data": barcodes.map({ $0.toMap() }), |
| 163 | ]) | 163 | ]) |
| 164 | return | 164 | return |
| 165 | } | 165 | } |
| 166 | - | 166 | + |
| 167 | + // The image dimensions are always provided. | ||
| 168 | + // The image bytes are only non-null when `returnImage` is true. | ||
| 169 | + let imageData: [String: Any?] = [ | ||
| 170 | + "bytes": MobileScannerPlugin.returnImage ? FlutterStandardTypedData(bytes: image.jpegData(compressionQuality: 0.8)!) : nil, | ||
| 171 | + "width": Double(image.width), | ||
| 172 | + "height": Double(image.height), | ||
| 173 | + ] | ||
| 174 | + | ||
| 167 | self?.sink?([ | 175 | self?.sink?([ |
| 168 | "name": "barcode", | 176 | "name": "barcode", |
| 169 | "data": barcodes.map({ $0.toMap() }), | 177 | "data": barcodes.map({ $0.toMap() }), |
| 170 | - "image": cgImage == nil ? nil : [ | ||
| 171 | - "bytes": FlutterStandardTypedData(bytes: cgImage!.jpegData(compressionQuality: 0.8)!), | ||
| 172 | - "width": Double(cgImage!.width), | ||
| 173 | - "height": Double(cgImage!.height), | ||
| 174 | - ], | 178 | + "image": imageData, |
| 175 | ]) | 179 | ]) |
| 176 | } | 180 | } |
| 177 | }) | 181 | }) |
-
Please register or login to post a comment