ryuta46

imp: add resetZoomScale

@@ -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.