Showing
5 changed files
with
81 additions
and
1 deletions
| @@ -289,4 +289,13 @@ class MobileScanner( | @@ -289,4 +289,13 @@ class MobileScanner( | ||
| 289 | camera!!.cameraControl.setLinearZoom(scale.toFloat()) | 289 | camera!!.cameraControl.setLinearZoom(scale.toFloat()) |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | + /** | ||
| 293 | + * Reset the zoom rate of the camera. | ||
| 294 | + */ | ||
| 295 | + fun resetScale() { | ||
| 296 | + if (camera == null) throw ZoomWhenStopped() | ||
| 297 | + camera!!.cameraControl.setZoomRatio(1f) | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + | ||
| 292 | } | 301 | } |
| @@ -120,6 +120,7 @@ class MobileScannerHandler( | @@ -120,6 +120,7 @@ class MobileScannerHandler( | ||
| 120 | "stop" -> stop(result) | 120 | "stop" -> stop(result) |
| 121 | "analyzeImage" -> analyzeImage(call, result) | 121 | "analyzeImage" -> analyzeImage(call, result) |
| 122 | "setScale" -> setScale(call, result) | 122 | "setScale" -> setScale(call, result) |
| 123 | + "resetScale" -> resetScale(call, result) | ||
| 123 | "updateScanWindow" -> updateScanWindow(call) | 124 | "updateScanWindow" -> updateScanWindow(call) |
| 124 | else -> result.notImplemented() | 125 | else -> result.notImplemented() |
| 125 | } | 126 | } |
| @@ -234,6 +235,15 @@ class MobileScannerHandler( | @@ -234,6 +235,15 @@ class MobileScannerHandler( | ||
| 234 | } | 235 | } |
| 235 | } | 236 | } |
| 236 | 237 | ||
| 238 | + private fun resetScale(call: MethodCall, result: MethodChannel.Result) { | ||
| 239 | + try { | ||
| 240 | + mobileScanner!!.resetScale() | ||
| 241 | + result.success(null) | ||
| 242 | + } catch (e: ZoomWhenStopped) { | ||
| 243 | + result.error("MobileScanner", "Called setScale() while stopped!", null) | ||
| 244 | + } | ||
| 245 | + } | ||
| 246 | + | ||
| 237 | private fun updateScanWindow(call: MethodCall) { | 247 | private fun updateScanWindow(call: MethodCall) { |
| 238 | mobileScanner!!.scanWindow = call.argument<List<Float>?>("rect") | 248 | mobileScanner!!.scanWindow = call.argument<List<Float>?>("rect") |
| 239 | } | 249 | } |
| @@ -52,6 +52,8 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -52,6 +52,8 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 52 | 52 | ||
| 53 | var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates | 53 | var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates |
| 54 | 54 | ||
| 55 | + var standardZoomFactor: CGFloat = 1 | ||
| 56 | + | ||
| 55 | init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) { | 57 | init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) { |
| 56 | self.registry = registry | 58 | self.registry = registry |
| 57 | self.mobileScannerCallback = mobileScannerCallback | 59 | self.mobileScannerCallback = mobileScannerCallback |
| @@ -140,6 +142,20 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -140,6 +142,20 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 140 | 142 | ||
| 141 | device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil) | 143 | device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil) |
| 142 | device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.videoZoomFactor), options: .new, context: nil) | 144 | device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.videoZoomFactor), options: .new, context: nil) |
| 145 | + | ||
| 146 | + // Check the zoom factor at switching from ultra wide camera to wide camera. | ||
| 147 | + standardZoomFactor = 1 | ||
| 148 | + if #available(iOS 13.0, *) { | ||
| 149 | + for (index, actualDevice) in device.constituentDevices.enumerated() { | ||
| 150 | + if (actualDevice.deviceType != .builtInUltraWideCamera) { | ||
| 151 | + if index > 0 && index <= device.virtualDeviceSwitchOverVideoZoomFactors.count { | ||
| 152 | + standardZoomFactor = CGFloat(truncating: device.virtualDeviceSwitchOverVideoZoomFactors[index - 1]) | ||
| 153 | + } | ||
| 154 | + break | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + } | ||
| 158 | + | ||
| 143 | do { | 159 | do { |
| 144 | try device.lockForConfiguration() | 160 | try device.lockForConfiguration() |
| 145 | if device.isFocusModeSupported(.continuousAutoFocus) { | 161 | if device.isFocusModeSupported(.continuousAutoFocus) { |
| @@ -272,6 +288,22 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | @@ -272,6 +288,22 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega | ||
| 272 | 288 | ||
| 273 | } | 289 | } |
| 274 | 290 | ||
| 291 | + /// Set the zoom factor of the camera | ||
| 292 | + func resetScale() throws { | ||
| 293 | + if (device == nil) { | ||
| 294 | + throw MobileScannerError.torchWhenStopped | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + do { | ||
| 298 | + try device.lockForConfiguration() | ||
| 299 | + device.videoZoomFactor = standardZoomFactor | ||
| 300 | + device.unlockForConfiguration() | ||
| 301 | + } catch { | ||
| 302 | + throw MobileScannerError.zoomError(error) | ||
| 303 | + } | ||
| 304 | + } | ||
| 305 | + | ||
| 306 | + | ||
| 275 | /// Analyze a single image | 307 | /// Analyze a single image |
| 276 | func analyzeImage(image: UIImage, position: AVCaptureDevice.Position, callback: @escaping BarcodeScanningCallback) { | 308 | func analyzeImage(image: UIImage, position: AVCaptureDevice.Position, callback: @escaping BarcodeScanningCallback) { |
| 277 | let image = VisionImage(image: image) | 309 | let image = VisionImage(image: image) |
| @@ -87,6 +87,8 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { | @@ -87,6 +87,8 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { | ||
| 87 | analyzeImage(call, result) | 87 | analyzeImage(call, result) |
| 88 | case "setScale": | 88 | case "setScale": |
| 89 | setScale(call, result) | 89 | setScale(call, result) |
| 90 | + case "resetScale": | ||
| 91 | + resetScale(call, result) | ||
| 90 | case "updateScanWindow": | 92 | case "updateScanWindow": |
| 91 | updateScanWindow(call, result) | 93 | updateScanWindow(call, result) |
| 92 | default: | 94 | default: |
| @@ -189,7 +191,28 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { | @@ -189,7 +191,28 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { | ||
| 189 | } | 191 | } |
| 190 | result(nil) | 192 | result(nil) |
| 191 | } | 193 | } |
| 192 | - | 194 | + |
| 195 | + /// Reset the zoomScale | ||
| 196 | + private func resetScale(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 197 | + do { | ||
| 198 | + try mobileScanner.resetScale() | ||
| 199 | + } catch MobileScannerError.zoomWhenStopped { | ||
| 200 | + result(FlutterError(code: "MobileScanner", | ||
| 201 | + message: "Called resetScale() while stopped!", | ||
| 202 | + details: nil)) | ||
| 203 | + } catch MobileScannerError.zoomError(let error) { | ||
| 204 | + result(FlutterError(code: "MobileScanner", | ||
| 205 | + message: "Error while zooming.", | ||
| 206 | + details: error)) | ||
| 207 | + } catch { | ||
| 208 | + result(FlutterError(code: "MobileScanner", | ||
| 209 | + message: "Error while zooming.", | ||
| 210 | + details: nil)) | ||
| 211 | + } | ||
| 212 | + result(nil) | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + | ||
| 193 | /// Toggles the torch | 216 | /// Toggles the torch |
| 194 | func updateScanWindow(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 217 | func updateScanWindow(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| 195 | let scanWindowData: Array? = (call.arguments as? [String: Any])?["rect"] as? [CGFloat] | 218 | let scanWindowData: Array? = (call.arguments as? [String: Any])?["rect"] as? [CGFloat] |
| @@ -322,6 +322,12 @@ class MobileScannerController { | @@ -322,6 +322,12 @@ class MobileScannerController { | ||
| 322 | await _methodChannel.invokeMethod('setScale', zoomScale); | 322 | await _methodChannel.invokeMethod('setScale', zoomScale); |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | + /// Reset the zoomScale of the camera to use standard scale 1x. | ||
| 326 | + Future<void> resetZoomScale() async { | ||
| 327 | + await _methodChannel.invokeMethod('resetScale'); | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + | ||
| 325 | /// Disposes the MobileScannerController and closes all listeners. | 331 | /// Disposes the MobileScannerController and closes all listeners. |
| 326 | /// | 332 | /// |
| 327 | /// If you call this, you cannot use this controller object anymore. | 333 | /// If you call this, you cannot use this controller object anymore. |
-
Please register or login to post a comment