Showing
4 changed files
with
81 additions
and
52 deletions
macos/Classes/DetectionSpeed.swift
0 → 100644
| 1 | import AVFoundation | 1 | import AVFoundation |
| 2 | import FlutterMacOS | 2 | import FlutterMacOS |
| 3 | import Vision | 3 | import Vision |
| 4 | -import UIKit | 4 | +import AppKit |
| 5 | 5 | ||
| 6 | public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate { | 6 | public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate { |
| 7 | 7 | ||
| @@ -25,6 +25,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -25,6 +25,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 25 | // optional window to limit scan search | 25 | // optional window to limit scan search |
| 26 | var scanWindow: CGRect? | 26 | var scanWindow: CGRect? |
| 27 | 27 | ||
| 28 | + var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates | ||
| 29 | + | ||
| 28 | 30 | ||
| 29 | // var analyzeMode: Int = 0 | 31 | // var analyzeMode: Int = 0 |
| 30 | var analyzing: Bool = false | 32 | var analyzing: Bool = false |
| @@ -93,58 +95,52 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -93,58 +95,52 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 93 | 95 | ||
| 94 | // Gets called when a new image is added to the buffer | 96 | // Gets called when a new image is added to the buffer |
| 95 | public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { | 97 | public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { |
| 96 | - i = i + 1; | ||
| 97 | - | ||
| 98 | - latestBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) | 98 | + guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { |
| 99 | + print("Failed to get image buffer from sample buffer.") | ||
| 100 | + return | ||
| 101 | + } | ||
| 102 | + latestBuffer = imageBuffer | ||
| 99 | registry.textureFrameAvailable(textureId) | 103 | registry.textureFrameAvailable(textureId) |
| 100 | - | ||
| 101 | -// switch analyzeMode { | ||
| 102 | -// case 1: // barcode | 104 | + |
| 105 | + if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && i > 10 || detectionSpeed == DetectionSpeed.unrestricted) { | ||
| 106 | + i = 0 | ||
| 107 | + let imageRequestHandler = VNImageRequestHandler( | ||
| 108 | + cvPixelBuffer: latestBuffer, | ||
| 109 | + orientation: .right) | ||
| 103 | 110 | ||
| 104 | - // Limit the analyzer because the texture output will freeze otherwise | ||
| 105 | - if i / 10 == 1 { | ||
| 106 | - i = 0 | ||
| 107 | - } else { | ||
| 108 | - return | ||
| 109 | - } | ||
| 110 | - let imageRequestHandler = VNImageRequestHandler( | ||
| 111 | - cvPixelBuffer: latestBuffer, | ||
| 112 | - orientation: .right) | ||
| 113 | - | ||
| 114 | - do { | ||
| 115 | - try imageRequestHandler.perform([VNDetectBarcodesRequest { (request, error) in | ||
| 116 | - if error == nil { | ||
| 117 | - if let results = request.results as? [VNBarcodeObservation] { | ||
| 118 | - for barcode in results { | ||
| 119 | - if scanWindow != nil { | ||
| 120 | - let match = isbarCodeInScanWindow(scanWindow!, barcode, buffer!.image) | ||
| 121 | - if (!match) { | ||
| 122 | - continue | 111 | + do { |
| 112 | + try imageRequestHandler.perform([VNDetectBarcodesRequest { (request, error) in | ||
| 113 | + if error == nil { | ||
| 114 | + if let results = request.results as? [VNBarcodeObservation] { | ||
| 115 | + for barcode in results { | ||
| 116 | + if self.scanWindow != nil { | ||
| 117 | + let match = self.isbarCodeInScanWindow(self.scanWindow!, barcode, self.latestBuffer) | ||
| 118 | + if (!match) { | ||
| 119 | + continue | ||
| 120 | + } | ||
| 123 | } | 121 | } |
| 124 | - } | ||
| 125 | 122 | ||
| 126 | - let barcodeType = String(barcode.symbology.rawValue).replacingOccurrences(of: "VNBarcodeSymbology", with: "") | ||
| 127 | - let event: [String: Any?] = ["name": "barcodeMac", "data" : ["payload": barcode.payloadStringValue, "symbology": barcodeType]] | ||
| 128 | - self.sink?(event) | 123 | + let barcodeType = String(barcode.symbology.rawValue).replacingOccurrences(of: "VNBarcodeSymbology", with: "") |
| 124 | + let event: [String: Any?] = ["name": "barcodeMac", "data" : ["payload": barcode.payloadStringValue, "symbology": barcodeType]] | ||
| 125 | + self.sink?(event) | ||
| 129 | 126 | ||
| 130 | - // if barcodeType == "QR" { | ||
| 131 | - // let image = CIImage(image: source) | ||
| 132 | - // image?.cropping(to: barcode.boundingBox) | ||
| 133 | - // self.qrCodeDescriptor(qrCode: barcode, qrCodeImage: image!) | ||
| 134 | - // } | ||
| 135 | - } | 127 | + // if barcodeType == "QR" { |
| 128 | + // let image = CIImage(image: source) | ||
| 129 | + // image?.cropping(to: barcode.boundingBox) | ||
| 130 | + // self.qrCodeDescriptor(qrCode: barcode, qrCodeImage: image!) | ||
| 131 | + // } | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + } else { | ||
| 135 | + print(error!.localizedDescription) | ||
| 136 | } | 136 | } |
| 137 | - } else { | ||
| 138 | - print(error!.localizedDescription) | ||
| 139 | - } | ||
| 140 | - }]) | ||
| 141 | - } catch { | ||
| 142 | - print(error) | ||
| 143 | - } | ||
| 144 | - | ||
| 145 | -// default: // none | ||
| 146 | -// break | ||
| 147 | -// } | 137 | + }]) |
| 138 | + } catch { | ||
| 139 | + print(error) | ||
| 140 | + } | ||
| 141 | + } else { | ||
| 142 | + i+=1 | ||
| 143 | + } | ||
| 148 | } | 144 | } |
| 149 | 145 | ||
| 150 | func checkPermission(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 146 | func checkPermission(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| @@ -188,11 +184,11 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -188,11 +184,11 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 188 | scanWindow = CGRect(x: minX, y: minY, width: width, height: height) | 184 | scanWindow = CGRect(x: minX, y: minY, width: width, height: height) |
| 189 | } | 185 | } |
| 190 | 186 | ||
| 191 | - func isbarCodeInScanWindow(_ scanWindow: CGRect, _ barcode: Barcode, _ inputImage: UIImage) -> Bool { | ||
| 192 | - let barcodeBoundingBox = barcode.frame | 187 | + func isbarCodeInScanWindow(_ scanWindow: CGRect, _ barcode: VNBarcodeObservation, _ inputImage: CVImageBuffer) -> Bool { |
| 188 | + let size = CVImageBufferGetEncodedSize(inputImage) | ||
| 193 | 189 | ||
| 194 | - let imageWidth = inputImage.size.width; | ||
| 195 | - let imageHeight = inputImage.size.height; | 190 | + let imageWidth = size.width; |
| 191 | + let imageHeight = size.height; | ||
| 196 | 192 | ||
| 197 | let minX = scanWindow.minX * imageWidth | 193 | let minX = scanWindow.minX * imageWidth |
| 198 | let minY = scanWindow.minY * imageHeight | 194 | let minY = scanWindow.minY * imageHeight |
| @@ -200,7 +196,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -200,7 +196,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 200 | let height = scanWindow.height * imageHeight | 196 | let height = scanWindow.height * imageHeight |
| 201 | 197 | ||
| 202 | let scaledScanWindow = CGRect(x: minX, y: minY, width: width, height: height) | 198 | let scaledScanWindow = CGRect(x: minX, y: minY, width: width, height: height) |
| 203 | - return scaledScanWindow.contains(barcodeBoundingBox) | 199 | + return scaledScanWindow.contains(barcode.boundingBox) |
| 204 | } | 200 | } |
| 205 | 201 | ||
| 206 | func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 202 | func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| @@ -219,6 +215,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -219,6 +215,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 219 | // let ratio: Int = argReader.int(key: "ratio") | 215 | // let ratio: Int = argReader.int(key: "ratio") |
| 220 | let torch: Bool = argReader.bool(key: "torch") ?? false | 216 | let torch: Bool = argReader.bool(key: "torch") ?? false |
| 221 | let facing: Int = argReader.int(key: "facing") ?? 1 | 217 | let facing: Int = argReader.int(key: "facing") ?? 1 |
| 218 | + let speed: Int = (call.arguments as! Dictionary<String, Any?>)["speed"] as? Int ?? 0 | ||
| 219 | + | ||
| 220 | + detectionSpeed = DetectionSpeed(rawValue: speed)! | ||
| 222 | 221 | ||
| 223 | // Set the camera to use | 222 | // Set the camera to use |
| 224 | position = facing == 0 ? AVCaptureDevice.Position.front : .back | 223 | position = facing == 0 ? AVCaptureDevice.Position.front : .back |
-
Please register or login to post a comment