Better memory footprint and using a dispatch queue
By not passing in the buffer to the barcode detect and using an image instead the footprint of the memory usage is significantly reduced.
Showing
1 changed file
with
178 additions
and
161 deletions
| @@ -2,6 +2,7 @@ import AVFoundation | @@ -2,6 +2,7 @@ import AVFoundation | ||
| 2 | import FlutterMacOS | 2 | import FlutterMacOS |
| 3 | import Vision | 3 | import Vision |
| 4 | import AppKit | 4 | import AppKit |
| 5 | +import VideoToolbox | ||
| 5 | 6 | ||
| 6 | public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate { | 7 | public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate { |
| 7 | 8 | ||
| @@ -17,8 +18,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -17,8 +18,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 17 | var captureSession: AVCaptureSession! | 18 | var captureSession: AVCaptureSession! |
| 18 | 19 | ||
| 19 | // The selected camera | 20 | // The selected camera |
| 20 | - var device: AVCaptureDevice! | ||
| 21 | - | 21 | + weak var device: AVCaptureDevice! |
| 22 | + | ||
| 22 | // Image to be sent to the texture | 23 | // Image to be sent to the texture |
| 23 | var latestBuffer: CVImageBuffer! | 24 | var latestBuffer: CVImageBuffer! |
| 24 | 25 | ||
| @@ -95,7 +96,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -95,7 +96,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | var nextScanTime = 0.0 | 98 | var nextScanTime = 0.0 |
| 98 | - var imagesCurrentlyBeingProcessed = 0 | 99 | + var imagesCurrentlyBeingProcessed = false |
| 99 | 100 | ||
| 100 | // Gets called when a new image is added to the buffer | 101 | // Gets called when a new image is added to the buffer |
| 101 | public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { | 102 | public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { |
| @@ -111,50 +112,53 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -111,50 +112,53 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 111 | registry.textureFrameAvailable(textureId) | 112 | registry.textureFrameAvailable(textureId) |
| 112 | 113 | ||
| 113 | let currentTime = Date().timeIntervalSince1970 | 114 | let currentTime = Date().timeIntervalSince1970 |
| 114 | - let eligibleForScan = currentTime > nextScanTime && imagesCurrentlyBeingProcessed == 0; | 115 | + let eligibleForScan = currentTime > nextScanTime && imagesCurrentlyBeingProcessed == false |
| 115 | if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && eligibleForScan || detectionSpeed == DetectionSpeed.unrestricted) { | 116 | if ((detectionSpeed == DetectionSpeed.normal || detectionSpeed == DetectionSpeed.noDuplicates) && eligibleForScan || detectionSpeed == DetectionSpeed.unrestricted) { |
| 116 | nextScanTime = currentTime + timeoutSeconds | 117 | nextScanTime = currentTime + timeoutSeconds |
| 117 | - imagesCurrentlyBeingProcessed += 1 | ||
| 118 | - let imageRequestHandler = VNImageRequestHandler( | ||
| 119 | - cvPixelBuffer: latestBuffer, | ||
| 120 | - orientation: .right) | ||
| 121 | - | 118 | + imagesCurrentlyBeingProcessed = true |
| 119 | + DispatchQueue.global(qos: .userInitiated).async { [weak self] in | ||
| 120 | + if(self!.latestBuffer == nil){ | ||
| 121 | + return | ||
| 122 | + } | ||
| 123 | + var cgImage: CGImage? | ||
| 124 | + VTCreateCGImageFromCVPixelBuffer(self!.latestBuffer, options: nil, imageOut: &cgImage) | ||
| 125 | + let imageRequestHandler = VNImageRequestHandler(cgImage: cgImage!) | ||
| 122 | do { | 126 | do { |
| 123 | - let barcodeRequest:VNDetectBarcodesRequest = VNDetectBarcodesRequest(completionHandler: { [self] (request, error) in | ||
| 124 | - imagesCurrentlyBeingProcessed -= 1 | ||
| 125 | - if error == nil { | ||
| 126 | - if let results = request.results as? [VNBarcodeObservation] { | 127 | + let barcodeRequest:VNDetectBarcodesRequest = VNDetectBarcodesRequest(completionHandler: { [weak self] (request, error) in |
| 128 | + self?.imagesCurrentlyBeingProcessed = false | ||
| 129 | + if error == nil { | ||
| 130 | + if let results = request.results as? [VNBarcodeObservation] { | ||
| 127 | for barcode in results { | 131 | for barcode in results { |
| 128 | - if self.scanWindow != nil { | ||
| 129 | - let match = self.isbarCodeInScanWindow(self.scanWindow!, barcode, self.latestBuffer) | ||
| 130 | - if (!match) { | 132 | + if self?.scanWindow != nil && cgImage != nil { |
| 133 | + let match = self?.isbarCodeInScanWindow(self!.scanWindow!, barcode, cgImage!) | ||
| 134 | + if (match == false) { | ||
| 131 | continue | 135 | continue |
| 132 | } | 136 | } |
| 133 | } | 137 | } |
| 134 | 138 | ||
| 135 | - let barcodeType = String(barcode.symbology.rawValue).replacingOccurrences(of: "VNBarcodeSymbology", with: "") | ||
| 136 | - let event: [String: Any?] = ["name": "barcodeMac", "data" : ["payload": barcode.payloadStringValue, "symbology": barcode.symbology.toInt as Any?]] | ||
| 137 | - self.sink?(event) | ||
| 138 | - | ||
| 139 | - // if barcodeType == "QR" { | ||
| 140 | - // let image = CIImage(image: source) | ||
| 141 | - // image?.cropping(to: barcode.boundingBox) | ||
| 142 | - // self.qrCodeDescriptor(qrCode: barcode, qrCodeImage: image!) | ||
| 143 | - // } | ||
| 144 | - } | ||
| 145 | - } | ||
| 146 | - } else { | ||
| 147 | - print(error!.localizedDescription) | ||
| 148 | - } | ||
| 149 | - }) | ||
| 150 | - if(symbologies.isEmpty == false){ | ||
| 151 | - // add the symbologies the user wishes to support | ||
| 152 | - barcodeRequest.symbologies = symbologies | ||
| 153 | - } | ||
| 154 | - try imageRequestHandler.perform([barcodeRequest]) | 139 | + DispatchQueue.main.async { |
| 140 | + self?.sink?(["name": "barcodeMac", "data" : ["payload": barcode.payloadStringValue, "symbology": barcode.symbology.toInt as Any?]] as [String : Any]) | ||
| 141 | + } | ||
| 142 | +// if barcodeType == "QR" { | ||
| 143 | +// let image = CIImage(image: source) | ||
| 144 | +// image?.cropping(to: barcode.boundingBox) | ||
| 145 | +// self.qrCodeDescriptor(qrCode: barcode, qrCodeImage: image!) | ||
| 146 | +// } | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + } else { | ||
| 150 | + print(error!.localizedDescription) | ||
| 151 | + } | ||
| 152 | + }) | ||
| 153 | + if(self?.symbologies.isEmpty == false){ | ||
| 154 | + // add the symbologies the user wishes to support | ||
| 155 | + barcodeRequest.symbologies = self!.symbologies | ||
| 156 | + } | ||
| 157 | + try imageRequestHandler.perform([barcodeRequest]) | ||
| 155 | } catch { | 158 | } catch { |
| 156 | - print(error) | 159 | + print(error) |
| 157 | } | 160 | } |
| 161 | + } | ||
| 158 | } | 162 | } |
| 159 | } | 163 | } |
| 160 | 164 | ||
| @@ -187,10 +191,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -187,10 +191,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 187 | let scanWindowData: Array? = argReader.floatArray(key: "rect") | 191 | let scanWindowData: Array? = argReader.floatArray(key: "rect") |
| 188 | 192 | ||
| 189 | if (scanWindowData == nil) { | 193 | if (scanWindowData == nil) { |
| 190 | - return | 194 | + return |
| 191 | } | 195 | } |
| 192 | 196 | ||
| 193 | - let minX = scanWindowData![0] | 197 | + let minX = scanWindowData![0] |
| 194 | let minY = scanWindowData![1] | 198 | let minY = scanWindowData![1] |
| 195 | 199 | ||
| 196 | let width = scanWindowData![2] - minX | 200 | let width = scanWindowData![2] - minX |
| @@ -198,9 +202,23 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -198,9 +202,23 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 198 | 202 | ||
| 199 | scanWindow = CGRect(x: minX, y: minY, width: width, height: height) | 203 | scanWindow = CGRect(x: minX, y: minY, width: width, height: height) |
| 200 | } | 204 | } |
| 205 | + | ||
| 206 | + func isbarCodeInScanWindow(_ scanWindow: CGRect, _ barcode: VNBarcodeObservation, _ inputImage: CGImage) -> Bool { | ||
| 207 | + | ||
| 208 | + let imageWidth = CGFloat(inputImage.width); | ||
| 209 | + let imageHeight = CGFloat(inputImage.height); | ||
| 210 | + | ||
| 211 | + let minX = scanWindow.minX * imageWidth | ||
| 212 | + let minY = scanWindow.minY * imageHeight | ||
| 213 | + let width = scanWindow.width * imageWidth | ||
| 214 | + let height = scanWindow.height * imageHeight | ||
| 215 | + | ||
| 216 | + let scaledScanWindow = CGRect(x: minX, y: minY, width: width, height: height) | ||
| 217 | + return scaledScanWindow.contains(barcode.boundingBox) | ||
| 218 | + } | ||
| 201 | 219 | ||
| 202 | func isbarCodeInScanWindow(_ scanWindow: CGRect, _ barcode: VNBarcodeObservation, _ inputImage: CVImageBuffer) -> Bool { | 220 | func isbarCodeInScanWindow(_ scanWindow: CGRect, _ barcode: VNBarcodeObservation, _ inputImage: CVImageBuffer) -> Bool { |
| 203 | - let size = CVImageBufferGetEncodedSize(inputImage) | 221 | + let size = CVImageBufferGetEncodedSize(inputImage) |
| 204 | 222 | ||
| 205 | let imageWidth = size.width; | 223 | let imageWidth = size.width; |
| 206 | let imageHeight = size.height; | 224 | let imageHeight = size.height; |
| @@ -217,22 +235,22 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -217,22 +235,22 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 217 | func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 235 | func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| 218 | if (device != nil) { | 236 | if (device != nil) { |
| 219 | result(FlutterError(code: "MobileScanner", | 237 | result(FlutterError(code: "MobileScanner", |
| 220 | - message: "Called start() while already started!", | ||
| 221 | - details: nil)) | 238 | + message: "Called start() while already started!", |
| 239 | + details: nil)) | ||
| 222 | return | 240 | return |
| 223 | } | 241 | } |
| 224 | - | 242 | + |
| 225 | textureId = registry.register(self) | 243 | textureId = registry.register(self) |
| 226 | captureSession = AVCaptureSession() | 244 | captureSession = AVCaptureSession() |
| 227 | - | 245 | + |
| 228 | let argReader = MapArgumentReader(call.arguments as? [String: Any]) | 246 | let argReader = MapArgumentReader(call.arguments as? [String: Any]) |
| 229 | - | ||
| 230 | -// let ratio: Int = argReader.int(key: "ratio") | ||
| 231 | - let torch: Bool = argReader.bool(key: "torch") ?? false | ||
| 232 | - let facing: Int = argReader.int(key: "facing") ?? 1 | ||
| 233 | - let speed: Int = (call.arguments as! Dictionary<String, Any?>)["speed"] as? Int ?? 0 | ||
| 234 | - let timeoutMs: Int = (call.arguments as! Dictionary<String, Any?>)["timeout"] as? Int ?? 0 | ||
| 235 | - symbologies = argReader.toSymbology() | 247 | + |
| 248 | + // let ratio: Int = argReader.int(key: "ratio") | ||
| 249 | + let torch:Bool = argReader.bool(key: "torch") ?? false | ||
| 250 | + let facing:Int = argReader.int(key: "facing") ?? 1 | ||
| 251 | + let speed:Int = argReader.int(key: "speed") ?? 0 | ||
| 252 | + let timeoutMs:Int = argReader.int(key: "timeout") ?? 0 | ||
| 253 | + symbologies = argReader.toSymbology() | ||
| 236 | 254 | ||
| 237 | timeoutSeconds = Double(timeoutMs) / 1000.0 | 255 | timeoutSeconds = Double(timeoutMs) / 1000.0 |
| 238 | detectionSpeed = DetectionSpeed(rawValue: speed)! | 256 | detectionSpeed = DetectionSpeed(rawValue: speed)! |
| @@ -249,8 +267,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -249,8 +267,8 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 249 | 267 | ||
| 250 | if (device == nil) { | 268 | if (device == nil) { |
| 251 | result(FlutterError(code: "MobileScanner", | 269 | result(FlutterError(code: "MobileScanner", |
| 252 | - message: "No camera found or failed to open camera!", | ||
| 253 | - details: nil)) | 270 | + message: "No camera found or failed to open camera!", |
| 271 | + details: nil)) | ||
| 254 | return | 272 | return |
| 255 | } | 273 | } |
| 256 | 274 | ||
| @@ -258,10 +276,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -258,10 +276,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 258 | if (device.hasTorch) { | 276 | if (device.hasTorch) { |
| 259 | do { | 277 | do { |
| 260 | try device.lockForConfiguration() | 278 | try device.lockForConfiguration() |
| 261 | - device.torchMode = torch ? .on : .off | ||
| 262 | - device.unlockForConfiguration() | ||
| 263 | - } catch { | ||
| 264 | - result(FlutterError(code: error.localizedDescription, message: nil, details: nil)) | 279 | + device.torchMode = torch ? .on : .off |
| 280 | + device.unlockForConfiguration() | ||
| 281 | + } catch { | ||
| 282 | + result(FlutterError(code: error.localizedDescription, message: nil, details: nil)) | ||
| 265 | } | 283 | } |
| 266 | } | 284 | } |
| 267 | 285 | ||
| @@ -285,7 +303,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -285,7 +303,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 285 | videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main) | 303 | videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main) |
| 286 | captureSession.addOutput(videoOutput) | 304 | captureSession.addOutput(videoOutput) |
| 287 | for connection in videoOutput.connections { | 305 | for connection in videoOutput.connections { |
| 288 | -// connection.videoOrientation = .portrait | 306 | + // connection.videoOrientation = .portrait |
| 289 | if position == .front && connection.isVideoMirroringSupported { | 307 | if position == .front && connection.isVideoMirroringSupported { |
| 290 | connection.isVideoMirrored = true | 308 | connection.isVideoMirrored = true |
| 291 | } | 309 | } |
| @@ -359,118 +377,117 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -359,118 +377,117 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 359 | 377 | ||
| 360 | class MapArgumentReader { | 378 | class MapArgumentReader { |
| 361 | 379 | ||
| 362 | - let args: [String: Any]? | ||
| 363 | - | ||
| 364 | - init(_ args: [String: Any]?) { | ||
| 365 | - self.args = args | ||
| 366 | - } | ||
| 367 | - | ||
| 368 | - func string(key: String) -> String? { | ||
| 369 | - return args?[key] as? String | ||
| 370 | - } | ||
| 371 | - | ||
| 372 | - func int(key: String) -> Int? { | ||
| 373 | - return (args?[key] as? NSNumber)?.intValue | ||
| 374 | - } | ||
| 375 | - | ||
| 376 | - func bool(key: String) -> Bool? { | ||
| 377 | - return (args?[key] as? NSNumber)?.boolValue | ||
| 378 | - } | ||
| 379 | - | ||
| 380 | - func stringArray(key: String) -> [String]? { | ||
| 381 | - return args?[key] as? [String] | ||
| 382 | - } | ||
| 383 | - | ||
| 384 | - func toSymbology() -> [VNBarcodeSymbology] { | ||
| 385 | - guard let syms:[Int] = args?["formats"] as? [Int] else { | ||
| 386 | - return [] | 380 | + let args: [String: Any]? |
| 381 | + | ||
| 382 | + init(_ args: [String: Any]?) { | ||
| 383 | + self.args = args | ||
| 384 | + } | ||
| 385 | + | ||
| 386 | + func string(key: String) -> String? { | ||
| 387 | + return args?[key] as? String | ||
| 388 | + } | ||
| 389 | + | ||
| 390 | + func int(key: String) -> Int? { | ||
| 391 | + return (args?[key] as? NSNumber)?.intValue | ||
| 387 | } | 392 | } |
| 388 | - if(syms.contains(0)){ | ||
| 389 | - return [] | 393 | + |
| 394 | + func bool(key: String) -> Bool? { | ||
| 395 | + return (args?[key] as? NSNumber)?.boolValue | ||
| 390 | } | 396 | } |
| 391 | - var barcodeFormats:[VNBarcodeSymbology] = [] | ||
| 392 | - syms.forEach { id in | ||
| 393 | - if let bc:VNBarcodeSymbology = VNBarcodeSymbology.fromInt(id) { | ||
| 394 | - barcodeFormats.append(bc) | ||
| 395 | - } | 397 | + |
| 398 | + func stringArray(key: String) -> [String]? { | ||
| 399 | + return args?[key] as? [String] | ||
| 400 | + } | ||
| 401 | + | ||
| 402 | + func toSymbology() -> [VNBarcodeSymbology] { | ||
| 403 | + guard let syms:[Int] = args?["formats"] as? [Int] else { | ||
| 404 | + return [] | ||
| 405 | + } | ||
| 406 | + if(syms.contains(0)){ | ||
| 407 | + return [] | ||
| 408 | + } | ||
| 409 | + var barcodeFormats:[VNBarcodeSymbology] = [] | ||
| 410 | + syms.forEach { id in | ||
| 411 | + if let bc:VNBarcodeSymbology = VNBarcodeSymbology.fromInt(id) { | ||
| 412 | + barcodeFormats.append(bc) | ||
| 413 | + } | ||
| 414 | + } | ||
| 415 | + return barcodeFormats | ||
| 396 | } | 416 | } |
| 397 | - return barcodeFormats | ||
| 398 | - } | ||
| 399 | 417 | ||
| 400 | - func floatArray(key: String) -> [CGFloat]? { | ||
| 401 | - return args?[key] as? [CGFloat] | ||
| 402 | - } | 418 | + func floatArray(key: String) -> [CGFloat]? { |
| 419 | + return args?[key] as? [CGFloat] | ||
| 420 | + } | ||
| 403 | 421 | ||
| 404 | } | 422 | } |
| 405 | 423 | ||
| 406 | extension VNBarcodeSymbology { | 424 | extension VNBarcodeSymbology { |
| 407 | 425 | ||
| 408 | - static func fromInt(_ mapValue:Int) -> VNBarcodeSymbology? { | ||
| 409 | - if #available(macOS 12.0, *) { | ||
| 410 | - if(mapValue == 8){ | ||
| 411 | - return VNBarcodeSymbology.codabar | ||
| 412 | - } | ||
| 413 | - } | ||
| 414 | - switch(mapValue){ | ||
| 415 | - case 1: | ||
| 416 | - return VNBarcodeSymbology.code128 | ||
| 417 | - case 2: | ||
| 418 | - return VNBarcodeSymbology.code39 | ||
| 419 | - case 4: | ||
| 420 | - return VNBarcodeSymbology.code93 | ||
| 421 | - case 16: | ||
| 422 | - return VNBarcodeSymbology.dataMatrix | ||
| 423 | - case 32: | ||
| 424 | - return VNBarcodeSymbology.ean13 | ||
| 425 | - case 64: | ||
| 426 | - return VNBarcodeSymbology.ean8 | ||
| 427 | - case 128: | ||
| 428 | - return VNBarcodeSymbology.itf14 | ||
| 429 | - case 256: | ||
| 430 | - return VNBarcodeSymbology.qr | ||
| 431 | - case 1024: | ||
| 432 | - return VNBarcodeSymbology.upce | ||
| 433 | - case 2048: | ||
| 434 | - return VNBarcodeSymbology.pdf417 | ||
| 435 | - case 4096: | ||
| 436 | - return VNBarcodeSymbology.aztec | ||
| 437 | - default: | ||
| 438 | - return nil | ||
| 439 | - } | ||
| 440 | - } | ||
| 441 | - | ||
| 442 | - var toInt:Int? { | ||
| 443 | - if #available(macOS 12.0, *) { | ||
| 444 | - if(self == VNBarcodeSymbology.codabar){ | ||
| 445 | - return 8 | ||
| 446 | - } | 426 | + static func fromInt(_ mapValue:Int) -> VNBarcodeSymbology? { |
| 427 | + if #available(macOS 12.0, *) { | ||
| 428 | + if(mapValue == 8){ | ||
| 429 | + return VNBarcodeSymbology.codabar | ||
| 430 | + } | ||
| 431 | + } | ||
| 432 | + switch(mapValue){ | ||
| 433 | + case 1: | ||
| 434 | + return VNBarcodeSymbology.code128 | ||
| 435 | + case 2: | ||
| 436 | + return VNBarcodeSymbology.code39 | ||
| 437 | + case 4: | ||
| 438 | + return VNBarcodeSymbology.code93 | ||
| 439 | + case 16: | ||
| 440 | + return VNBarcodeSymbology.dataMatrix | ||
| 441 | + case 32: | ||
| 442 | + return VNBarcodeSymbology.ean13 | ||
| 443 | + case 64: | ||
| 444 | + return VNBarcodeSymbology.ean8 | ||
| 445 | + case 128: | ||
| 446 | + return VNBarcodeSymbology.itf14 | ||
| 447 | + case 256: | ||
| 448 | + return VNBarcodeSymbology.qr | ||
| 449 | + case 1024: | ||
| 450 | + return VNBarcodeSymbology.upce | ||
| 451 | + case 2048: | ||
| 452 | + return VNBarcodeSymbology.pdf417 | ||
| 453 | + case 4096: | ||
| 454 | + return VNBarcodeSymbology.aztec | ||
| 455 | + default: | ||
| 456 | + return nil | ||
| 457 | + } | ||
| 447 | } | 458 | } |
| 448 | - switch(self){ | ||
| 449 | - case VNBarcodeSymbology.code128: | ||
| 450 | - return 1 | ||
| 451 | - case VNBarcodeSymbology.code39: | ||
| 452 | - return 2 | ||
| 453 | - case VNBarcodeSymbology.code93: | ||
| 454 | - return 4 | ||
| 455 | - case VNBarcodeSymbology.dataMatrix: | ||
| 456 | - return 16 | ||
| 457 | - case VNBarcodeSymbology.ean13: | ||
| 458 | - return 32 | ||
| 459 | - case VNBarcodeSymbology.ean8: | ||
| 460 | - return 64 | ||
| 461 | - case VNBarcodeSymbology.itf14: | ||
| 462 | - return 128 | ||
| 463 | - case VNBarcodeSymbology.qr: | ||
| 464 | - return 256 | ||
| 465 | - case VNBarcodeSymbology.upce: | ||
| 466 | - return 1024 | ||
| 467 | - case VNBarcodeSymbology.pdf417: | ||
| 468 | - return 2048 | ||
| 469 | - case VNBarcodeSymbology.aztec: | ||
| 470 | - return 4096 | ||
| 471 | - default: | ||
| 472 | - return -1; | 459 | + |
| 460 | + var toInt:Int? { | ||
| 461 | + if #available(macOS 12.0, *) { | ||
| 462 | + if(self == VNBarcodeSymbology.codabar){ | ||
| 463 | + return 8 | ||
| 464 | + } | ||
| 465 | + } | ||
| 466 | + switch(self){ | ||
| 467 | + case VNBarcodeSymbology.code128: | ||
| 468 | + return 1 | ||
| 469 | + case VNBarcodeSymbology.code39: | ||
| 470 | + return 2 | ||
| 471 | + case VNBarcodeSymbology.code93: | ||
| 472 | + return 4 | ||
| 473 | + case VNBarcodeSymbology.dataMatrix: | ||
| 474 | + return 16 | ||
| 475 | + case VNBarcodeSymbology.ean13: | ||
| 476 | + return 32 | ||
| 477 | + case VNBarcodeSymbology.ean8: | ||
| 478 | + return 64 | ||
| 479 | + case VNBarcodeSymbology.itf14: | ||
| 480 | + return 128 | ||
| 481 | + case VNBarcodeSymbology.qr: | ||
| 482 | + return 256 | ||
| 483 | + case VNBarcodeSymbology.upce: | ||
| 484 | + return 1024 | ||
| 485 | + case VNBarcodeSymbology.pdf417: | ||
| 486 | + return 2048 | ||
| 487 | + case VNBarcodeSymbology.aztec: | ||
| 488 | + return 4096 | ||
| 489 | + default: | ||
| 490 | + return -1; | ||
| 491 | + } | ||
| 473 | } | 492 | } |
| 474 | - } | ||
| 475 | - | ||
| 476 | } | 493 | } |
-
Please register or login to post a comment