Julian Steenbakker

imp: fix build on macos

  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "group:Runner.xcodeproj">
  6 + </FileRef>
  7 + <FileRef
  8 + location = "group:Pods/Pods.xcodeproj">
  9 + </FileRef>
  10 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
  1 +//
  2 +// DetectionSpeed.swift
  3 +// mobile_scanner
  4 +//
  5 +// Created by Julian Steenbakker on 11/11/2022.
  6 +//
  7 +
  8 +enum DetectionSpeed: Int {
  9 + case noDuplicates = 0
  10 + case normal = 1
  11 + case unrestricted = 2
  12 +}
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