Showing
6 changed files
with
35 additions
and
2 deletions
| @@ -138,6 +138,7 @@ class MobileScanner( | @@ -138,6 +138,7 @@ class MobileScanner( | ||
| 138 | torch: Boolean, | 138 | torch: Boolean, |
| 139 | detectionSpeed: DetectionSpeed, | 139 | detectionSpeed: DetectionSpeed, |
| 140 | torchStateCallback: TorchStateCallback, | 140 | torchStateCallback: TorchStateCallback, |
| 141 | + zoomScaleStateCallback: ZoomScaleStateCallback, | ||
| 141 | mobileScannerStartedCallback: MobileScannerStartedCallback, | 142 | mobileScannerStartedCallback: MobileScannerStartedCallback, |
| 142 | detectionTimeout: Long | 143 | detectionTimeout: Long |
| 143 | ) { | 144 | ) { |
| @@ -201,6 +202,11 @@ class MobileScanner( | @@ -201,6 +202,11 @@ class MobileScanner( | ||
| 201 | torchStateCallback(state) | 202 | torchStateCallback(state) |
| 202 | } | 203 | } |
| 203 | 204 | ||
| 205 | + // Register the zoom scale listener | ||
| 206 | + camera!!.cameraInfo.zoomState.observe(activity) { state -> | ||
| 207 | + zoomScaleStateCallback(state.linearZoom.toDouble()) | ||
| 208 | + } | ||
| 209 | + | ||
| 204 | 210 | ||
| 205 | // Enable torch if provided | 211 | // Enable torch if provided |
| 206 | camera!!.cameraControl.enableTorch(torch) | 212 | camera!!.cameraControl.enableTorch(torch) |
| @@ -6,4 +6,5 @@ typealias MobileScannerCallback = (barcodes: List<Map<String, Any?>>, image: Byt | @@ -6,4 +6,5 @@ typealias MobileScannerCallback = (barcodes: List<Map<String, Any?>>, image: Byt | ||
| 6 | typealias AnalyzerCallback = (barcodes: List<Map<String, Any?>>?) -> Unit | 6 | typealias AnalyzerCallback = (barcodes: List<Map<String, Any?>>?) -> Unit |
| 7 | typealias MobileScannerErrorCallback = (error: String) -> Unit | 7 | typealias MobileScannerErrorCallback = (error: String) -> Unit |
| 8 | typealias TorchStateCallback = (state: Int) -> Unit | 8 | typealias TorchStateCallback = (state: Int) -> Unit |
| 9 | +typealias ZoomScaleStateCallback = (zoomScale: Double) -> Unit | ||
| 9 | typealias MobileScannerStartedCallback = (parameters: MobileScannerStartParameters) -> Unit | 10 | typealias MobileScannerStartedCallback = (parameters: MobileScannerStartParameters) -> Unit |
| @@ -70,6 +70,11 @@ class MobileScannerHandler( | @@ -70,6 +70,11 @@ class MobileScannerHandler( | ||
| 70 | barcodeHandler.publishEvent(mapOf("name" to "torchState", "data" to state)) | 70 | barcodeHandler.publishEvent(mapOf("name" to "torchState", "data" to state)) |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | + private val zoomScaleStateCallback: ZoomScaleStateCallback = {zoomScale: Double -> | ||
| 74 | + barcodeHandler.publishEvent(mapOf("name" to "zoomScaleState", "data" to zoomScale)) | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + | ||
| 73 | init { | 78 | init { |
| 74 | methodChannel = MethodChannel(binaryMessenger, | 79 | methodChannel = MethodChannel(binaryMessenger, |
| 75 | "dev.steenbakker.mobile_scanner/scanner/method") | 80 | "dev.steenbakker.mobile_scanner/scanner/method") |
| @@ -152,7 +157,7 @@ class MobileScannerHandler( | @@ -152,7 +157,7 @@ class MobileScannerHandler( | ||
| 152 | val detectionSpeed: DetectionSpeed = DetectionSpeed.values().first { it.intValue == speed} | 157 | val detectionSpeed: DetectionSpeed = DetectionSpeed.values().first { it.intValue == speed} |
| 153 | 158 | ||
| 154 | try { | 159 | try { |
| 155 | - mobileScanner!!.start(barcodeScannerOptions, returnImage, position, torch, detectionSpeed, torchStateCallback, mobileScannerStartedCallback = { | 160 | + mobileScanner!!.start(barcodeScannerOptions, returnImage, position, torch, detectionSpeed, torchStateCallback, zoomScaleStateCallback, mobileScannerStartedCallback = { |
| 156 | result.success(mapOf( | 161 | result.success(mapOf( |
| 157 | "textureId" to it.id, | 162 | "textureId" to it.id, |
| 158 | "size" to mapOf("width" to it.width, "height" to it.height), | 163 | "size" to mapOf("width" to it.width, "height" to it.height), |
| @@ -13,6 +13,7 @@ import MLKitBarcodeScanning | @@ -13,6 +13,7 @@ import MLKitBarcodeScanning | ||
| 13 | 13 | ||
| 14 | typealias MobileScannerCallback = ((Array<Barcode>?, Error?, UIImage) -> ()) | 14 | typealias MobileScannerCallback = ((Array<Barcode>?, Error?, UIImage) -> ()) |
| 15 | typealias TorchModeChangeCallback = ((Int?) -> ()) | 15 | typealias TorchModeChangeCallback = ((Int?) -> ()) |
| 16 | +typealias ZoomScaleChangeCallback = ((Double?) -> ()) | ||
| 16 | 17 | ||
| 17 | public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, FlutterTexture { | 18 | public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, FlutterTexture { |
| 18 | /// Capture session of the camera | 19 | /// Capture session of the camera |
| @@ -36,6 +37,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -36,6 +37,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 36 | /// When torch mode is changes, this callback will be called | 37 | /// When torch mode is changes, this callback will be called |
| 37 | let torchModeChangeCallback: TorchModeChangeCallback | 38 | let torchModeChangeCallback: TorchModeChangeCallback |
| 38 | 39 | ||
| 40 | + /// When zoom scale is changes, this callback will be called | ||
| 41 | + let zoomScaleChangeCallback: ZoomScaleChangeCallback | ||
| 42 | + | ||
| 43 | + | ||
| 39 | /// If provided, the Flutter registry will be used to send the output of the CaptureOutput to a Flutter texture. | 44 | /// If provided, the Flutter registry will be used to send the output of the CaptureOutput to a Flutter texture. |
| 40 | private let registry: FlutterTextureRegistry? | 45 | private let registry: FlutterTextureRegistry? |
| 41 | 46 | ||
| @@ -47,10 +52,11 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -47,10 +52,11 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 47 | 52 | ||
| 48 | var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates | 53 | var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates |
| 49 | 54 | ||
| 50 | - init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback) { | 55 | + init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) { |
| 51 | self.registry = registry | 56 | self.registry = registry |
| 52 | self.mobileScannerCallback = mobileScannerCallback | 57 | self.mobileScannerCallback = mobileScannerCallback |
| 53 | self.torchModeChangeCallback = torchModeChangeCallback | 58 | self.torchModeChangeCallback = torchModeChangeCallback |
| 59 | + self.zoomScaleChangeCallback = zoomScaleChangeCallback | ||
| 54 | super.init() | 60 | super.init() |
| 55 | } | 61 | } |
| 56 | 62 | ||
| @@ -133,6 +139,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -133,6 +139,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 133 | } | 139 | } |
| 134 | 140 | ||
| 135 | device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil) | 141 | device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil) |
| 142 | + device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.videoZoomFactor), options: .new, context: nil) | ||
| 136 | do { | 143 | do { |
| 137 | try device.lockForConfiguration() | 144 | try device.lockForConfiguration() |
| 138 | if device.isFocusModeSupported(.continuousAutoFocus) { | 145 | if device.isFocusModeSupported(.continuousAutoFocus) { |
| @@ -199,6 +206,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -199,6 +206,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 199 | captureSession.removeOutput(output) | 206 | captureSession.removeOutput(output) |
| 200 | } | 207 | } |
| 201 | device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode)) | 208 | device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode)) |
| 209 | + device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.videoZoomFactor)) | ||
| 202 | registry?.unregisterTexture(textureId) | 210 | registry?.unregisterTexture(textureId) |
| 203 | textureId = nil | 211 | textureId = nil |
| 204 | captureSession = nil | 212 | captureSession = nil |
| @@ -228,6 +236,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -228,6 +236,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 228 | // off = 0; on = 1; auto = 2; | 236 | // off = 0; on = 1; auto = 2; |
| 229 | let state = change?[.newKey] as? Int | 237 | let state = change?[.newKey] as? Int |
| 230 | torchModeChangeCallback(state) | 238 | torchModeChangeCallback(state) |
| 239 | + case "videoZoomFactor": | ||
| 240 | + let zoomFactor = change?[.newKey] as? CGFloat ?? 1 | ||
| 241 | + let zoomScale = (zoomFactor - 1) / 4 | ||
| 242 | + zoomScaleChangeCallback(Double(zoomScale)) | ||
| 231 | default: | 243 | default: |
| 232 | break | 244 | break |
| 233 | } | 245 | } |
| @@ -57,6 +57,8 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { | @@ -57,6 +57,8 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { | ||
| 57 | } | 57 | } |
| 58 | }, torchModeChangeCallback: { torchState in | 58 | }, torchModeChangeCallback: { torchState in |
| 59 | barcodeHandler.publishEvent(["name": "torchState", "data": torchState]) | 59 | barcodeHandler.publishEvent(["name": "torchState", "data": torchState]) |
| 60 | + }, zoomScaleChangeCallback: { zoomScale in | ||
| 61 | + barcodeHandler.publishEvent(["name": "zoomScaleState", "data": zoomScale]) | ||
| 60 | }) | 62 | }) |
| 61 | self.barcodeHandler = barcodeHandler | 63 | self.barcodeHandler = barcodeHandler |
| 62 | super.init() | 64 | super.init() |
| @@ -85,6 +85,10 @@ class MobileScannerController { | @@ -85,6 +85,10 @@ class MobileScannerController { | ||
| 85 | late final ValueNotifier<CameraFacing> cameraFacingState = | 85 | late final ValueNotifier<CameraFacing> cameraFacingState = |
| 86 | ValueNotifier(facing); | 86 | ValueNotifier(facing); |
| 87 | 87 | ||
| 88 | + /// A notifier that provides zoomScale. | ||
| 89 | + final ValueNotifier<double> zoomScaleState = ValueNotifier(0.0); | ||
| 90 | + | ||
| 91 | + | ||
| 88 | bool isStarting = false; | 92 | bool isStarting = false; |
| 89 | 93 | ||
| 90 | /// A notifier that provides availability of the Torch (Flash) | 94 | /// A notifier that provides availability of the Torch (Flash) |
| @@ -337,6 +341,9 @@ class MobileScannerController { | @@ -337,6 +341,9 @@ class MobileScannerController { | ||
| 337 | final state = TorchState.values[data as int? ?? 0]; | 341 | final state = TorchState.values[data as int? ?? 0]; |
| 338 | torchState.value = state; | 342 | torchState.value = state; |
| 339 | break; | 343 | break; |
| 344 | + case 'zoomScaleState': | ||
| 345 | + zoomScaleState.value = data as double? ?? 0.0; | ||
| 346 | + break; | ||
| 340 | case 'barcode': | 347 | case 'barcode': |
| 341 | if (data == null) return; | 348 | if (data == null) return; |
| 342 | final parsed = (data as List) | 349 | final parsed = (data as List) |
-
Please register or login to post a comment