Showing
7 changed files
with
79 additions
and
80 deletions
| 1 | package dev.steenbakker.mobile_scanner | 1 | package dev.steenbakker.mobile_scanner |
| 2 | 2 | ||
| 3 | import com.google.mlkit.vision.barcode.BarcodeScannerOptions | 3 | import com.google.mlkit.vision.barcode.BarcodeScannerOptions |
| 4 | -import java.util.ArrayList | ||
| 5 | 4 | ||
| 6 | enum class BarcodeFormats(val intValue: Int) { | 5 | enum class BarcodeFormats(val intValue: Int) { |
| 6 | + UNKNOWN(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_UNKNOWN), | ||
| 7 | ALL_FORMATS(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_ALL_FORMATS), CODE_128(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_CODE_128), CODE_39( | 7 | ALL_FORMATS(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_ALL_FORMATS), CODE_128(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_CODE_128), CODE_39( |
| 8 | com.google.mlkit.vision.barcode.common.Barcode.FORMAT_CODE_39 | 8 | com.google.mlkit.vision.barcode.common.Barcode.FORMAT_CODE_39 |
| 9 | ), | 9 | ), |
| @@ -17,76 +17,4 @@ enum class BarcodeFormats(val intValue: Int) { | @@ -17,76 +17,4 @@ enum class BarcodeFormats(val intValue: Int) { | ||
| 17 | com.google.mlkit.vision.barcode.common.Barcode.FORMAT_UPC_E | 17 | com.google.mlkit.vision.barcode.common.Barcode.FORMAT_UPC_E |
| 18 | ), | 18 | ), |
| 19 | PDF417(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_PDF417), AZTEC(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_AZTEC); | 19 | PDF417(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_PDF417), AZTEC(com.google.mlkit.vision.barcode.common.Barcode.FORMAT_AZTEC); |
| 20 | - | ||
| 21 | - companion object { | ||
| 22 | - private var formatsMap: MutableMap<String, Int>? = null | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * Return the integer value resuling from OR-ing all of the values | ||
| 26 | - * of the supplied strings. | ||
| 27 | - * | ||
| 28 | - * | ||
| 29 | - * Note that if ALL_FORMATS is defined as well as other values, ALL_FORMATS | ||
| 30 | - * will be ignored (following how it would work with just OR-ing the ints). | ||
| 31 | - * | ||
| 32 | - * @param strings - list of strings representing the various formats | ||
| 33 | - * @return integer value corresponding to OR of all the values. | ||
| 34 | - */ | ||
| 35 | - fun intFromStringList(strings: List<String>?): Int { | ||
| 36 | - if (strings == null) return ALL_FORMATS.intValue | ||
| 37 | - var `val` = 0 | ||
| 38 | - for (string in strings) { | ||
| 39 | - val asInt = formatsMap!![string] | ||
| 40 | - if (asInt != null) { | ||
| 41 | - `val` = `val` or asInt | ||
| 42 | - } | ||
| 43 | - } | ||
| 44 | - return `val` | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - fun optionsFromStringList(strings: List<String>?): BarcodeScannerOptions { | ||
| 48 | - if (strings == null) { | ||
| 49 | - return BarcodeScannerOptions.Builder().setBarcodeFormats(ALL_FORMATS.intValue) | ||
| 50 | - .build() | ||
| 51 | - } | ||
| 52 | - val ints: MutableList<Int> = ArrayList(strings.size) | ||
| 53 | - run { | ||
| 54 | - var i = 0 | ||
| 55 | - val l = strings.size | ||
| 56 | - while (i < l) { | ||
| 57 | - val integer = | ||
| 58 | - formatsMap!![strings[i]] | ||
| 59 | - if (integer != null) { | ||
| 60 | - ints.add(integer) | ||
| 61 | - } | ||
| 62 | - ++i | ||
| 63 | - } | ||
| 64 | - } | ||
| 65 | - if (ints.size == 0) { | ||
| 66 | - return BarcodeScannerOptions.Builder().setBarcodeFormats(ALL_FORMATS.intValue) | ||
| 67 | - .build() | ||
| 68 | - } | ||
| 69 | - if (ints.size == 1) { | ||
| 70 | - return BarcodeScannerOptions.Builder().setBarcodeFormats(ints[0]).build() | ||
| 71 | - } | ||
| 72 | - val first = ints[0] | ||
| 73 | - val rest = IntArray(ints.size - 1) | ||
| 74 | - var i = 0 | ||
| 75 | - for (e in ints.subList(1, ints.size)) { | ||
| 76 | - rest[i++] = e | ||
| 77 | - } | ||
| 78 | - return BarcodeScannerOptions.Builder() | ||
| 79 | - .setBarcodeFormats(first, *rest).build() | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - init { | ||
| 83 | - val values = values() | ||
| 84 | - formatsMap = | ||
| 85 | - HashMap<String, Int>(values.size * 4 / 3) | ||
| 86 | - for (value in values) { | ||
| 87 | - formatsMap!![value.name] = | ||
| 88 | - value.intValue | ||
| 89 | - } | ||
| 90 | - } | ||
| 91 | - } | ||
| 92 | } | 20 | } |
| @@ -128,11 +128,18 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -128,11 +128,18 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 128 | val facing: Int = call.argument<Int>("facing") ?: 0 | 128 | val facing: Int = call.argument<Int>("facing") ?: 0 |
| 129 | val ratio: Int? = call.argument<Int>("ratio") | 129 | val ratio: Int? = call.argument<Int>("ratio") |
| 130 | val torch: Boolean = call.argument<Boolean>("torch") ?: false | 130 | val torch: Boolean = call.argument<Boolean>("torch") ?: false |
| 131 | - val formatStrings: List<String>? = call.argument<List<String>>("formats") | 131 | + val formats: List<Int>? = call.argument<List<Int>>("formats") |
| 132 | 132 | ||
| 133 | - if (formatStrings != null) { | ||
| 134 | - val options: BarcodeScannerOptions = BarcodeFormats.optionsFromStringList(formatStrings) | ||
| 135 | - scanner = BarcodeScanning.getClient(options) | 133 | + if (formats != null) { |
| 134 | + val formatsList: MutableList<Int> = mutableListOf() | ||
| 135 | + for (index in formats) { | ||
| 136 | + formatsList.add(BarcodeFormats.values()[index].intValue) | ||
| 137 | + } | ||
| 138 | + scanner = if (formatsList.size == 1) { | ||
| 139 | + BarcodeScanning.getClient( BarcodeScannerOptions.Builder().setBarcodeFormats(formatsList.first()).build()); | ||
| 140 | + } else { | ||
| 141 | + BarcodeScanning.getClient( BarcodeScannerOptions.Builder().setBarcodeFormats(formatsList.first(), *formatsList.subList(1, formatsList.size).toIntArray() ).build()); | ||
| 142 | + } | ||
| 136 | } | 143 | } |
| 137 | 144 | ||
| 138 | val future = ProcessCameraProvider.getInstance(activity) | 145 | val future = ProcessCameraProvider.getInstance(activity) |
| @@ -17,6 +17,7 @@ class _BarcodeScannerWithControllerState | @@ -17,6 +17,7 @@ class _BarcodeScannerWithControllerState | ||
| 17 | 17 | ||
| 18 | MobileScannerController controller = MobileScannerController( | 18 | MobileScannerController controller = MobileScannerController( |
| 19 | torchEnabled: true, | 19 | torchEnabled: true, |
| 20 | + // formats: [BarcodeFormat.ean13, BarcodeFormat.ean8] | ||
| 20 | // facing: CameraFacing.front, | 21 | // facing: CameraFacing.front, |
| 21 | ); | 22 | ); |
| 22 | 23 |
| @@ -26,7 +26,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -26,7 +26,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 26 | var analyzing: Bool = false | 26 | var analyzing: Bool = false |
| 27 | var position = AVCaptureDevice.Position.back | 27 | var position = AVCaptureDevice.Position.back |
| 28 | 28 | ||
| 29 | - let scanner = BarcodeScanner.barcodeScanner() | 29 | + var scanner = BarcodeScanner.barcodeScanner() |
| 30 | 30 | ||
| 31 | public static func register(with registrar: FlutterPluginRegistrar) { | 31 | public static func register(with registrar: FlutterPluginRegistrar) { |
| 32 | let instance = SwiftMobileScannerPlugin(registrar.textures()) | 32 | let instance = SwiftMobileScannerPlugin(registrar.textures()) |
| @@ -171,6 +171,15 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -171,6 +171,15 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 171 | // let ratio: Int = argReader.int(key: "ratio") | 171 | // let ratio: Int = argReader.int(key: "ratio") |
| 172 | let torch: Bool = argReader.bool(key: "torch") ?? false | 172 | let torch: Bool = argReader.bool(key: "torch") ?? false |
| 173 | let facing: Int = argReader.int(key: "facing") ?? 1 | 173 | let facing: Int = argReader.int(key: "facing") ?? 1 |
| 174 | + let formats: Array = argReader.intArray(key: "formats") ?? [] | ||
| 175 | + | ||
| 176 | + let formatList: NSMutableArray = [] | ||
| 177 | + for index in formats { | ||
| 178 | + formatList.add(BarcodeFormat(rawValue: index)) | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + let barcodeOptions = BarcodeScannerOptions(formats: formatList.firstObject as! BarcodeFormat) | ||
| 182 | + scanner = BarcodeScanner.barcodeScanner(options: barcodeOptions) | ||
| 174 | 183 | ||
| 175 | // Set the camera to use | 184 | // Set the camera to use |
| 176 | position = facing == 0 ? AVCaptureDevice.Position.front : .back | 185 | position = facing == 0 ? AVCaptureDevice.Position.front : .back |
| @@ -357,4 +366,8 @@ class MapArgumentReader { | @@ -357,4 +366,8 @@ class MapArgumentReader { | ||
| 357 | return args?[key] as? [String] | 366 | return args?[key] as? [String] |
| 358 | } | 367 | } |
| 359 | 368 | ||
| 369 | + func intArray(key: String) -> [Int]? { | ||
| 370 | + return args?[key] as? [Int] | ||
| 371 | + } | ||
| 372 | + | ||
| 360 | } | 373 | } |
| @@ -28,7 +28,7 @@ class MobileScanner extends StatefulWidget { | @@ -28,7 +28,7 @@ class MobileScanner extends StatefulWidget { | ||
| 28 | Key? key, | 28 | Key? key, |
| 29 | this.onDetect, | 29 | this.onDetect, |
| 30 | this.controller, | 30 | this.controller, |
| 31 | - this.fit = BoxFit.cover, | 31 | + this.fit = BoxFit.cover |
| 32 | }) : super(key: key); | 32 | }) : super(key: key); |
| 33 | 33 | ||
| 34 | @override | 34 | @override |
| 1 | import 'dart:async'; | 1 | import 'dart:async'; |
| 2 | +import 'dart:io'; | ||
| 2 | 3 | ||
| 3 | import 'package:flutter/cupertino.dart'; | 4 | import 'package:flutter/cupertino.dart'; |
| 4 | import 'package:flutter/services.dart'; | 5 | import 'package:flutter/services.dart'; |
| @@ -42,6 +43,7 @@ class MobileScannerController { | @@ -42,6 +43,7 @@ class MobileScannerController { | ||
| 42 | late final ValueNotifier<CameraFacing> cameraFacingState; | 43 | late final ValueNotifier<CameraFacing> cameraFacingState; |
| 43 | final Ratio? ratio; | 44 | final Ratio? ratio; |
| 44 | final bool? torchEnabled; | 45 | final bool? torchEnabled; |
| 46 | + final List<BarcodeFormat>? formats; | ||
| 45 | 47 | ||
| 46 | CameraFacing facing; | 48 | CameraFacing facing; |
| 47 | bool hasTorch = false; | 49 | bool hasTorch = false; |
| @@ -50,7 +52,7 @@ class MobileScannerController { | @@ -50,7 +52,7 @@ class MobileScannerController { | ||
| 50 | Stream<Barcode> get barcodes => barcodesController.stream; | 52 | Stream<Barcode> get barcodes => barcodesController.stream; |
| 51 | 53 | ||
| 52 | MobileScannerController( | 54 | MobileScannerController( |
| 53 | - {this.facing = CameraFacing.back, this.ratio, this.torchEnabled}) { | 55 | + {this.facing = CameraFacing.back, this.ratio, this.torchEnabled, this.formats}) { |
| 54 | // In case a new instance is created before calling dispose() | 56 | // In case a new instance is created before calling dispose() |
| 55 | if (_controllerHashcode != null) { | 57 | if (_controllerHashcode != null) { |
| 56 | stop(); | 58 | stop(); |
| @@ -138,6 +140,15 @@ class MobileScannerController { | @@ -138,6 +140,15 @@ class MobileScannerController { | ||
| 138 | if (ratio != null) arguments['ratio'] = ratio; | 140 | if (ratio != null) arguments['ratio'] = ratio; |
| 139 | if (torchEnabled != null) arguments['torch'] = torchEnabled; | 141 | if (torchEnabled != null) arguments['torch'] = torchEnabled; |
| 140 | 142 | ||
| 143 | + if (formats != null) { | ||
| 144 | + if (Platform.isAndroid) { | ||
| 145 | + arguments['formats'] = formats!.map((e) => e.index).toList(); | ||
| 146 | + } else if (Platform.isIOS || Platform.isMacOS) { | ||
| 147 | + arguments['formats'] = formats!.map((e) => e.rawValue).toList(); | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + } | ||
| 151 | + | ||
| 141 | // Start the camera with arguments | 152 | // Start the camera with arguments |
| 142 | Map<String, dynamic>? startResult = {}; | 153 | Map<String, dynamic>? startResult = {}; |
| 143 | try { | 154 | try { |
| @@ -553,6 +553,45 @@ enum BarcodeFormat { | @@ -553,6 +553,45 @@ enum BarcodeFormat { | ||
| 553 | aztec, | 553 | aztec, |
| 554 | } | 554 | } |
| 555 | 555 | ||
| 556 | +extension BarcodeValue on BarcodeFormat { | ||
| 557 | + | ||
| 558 | + int get rawValue { | ||
| 559 | + switch (this) { | ||
| 560 | + case BarcodeFormat.unknown: | ||
| 561 | + return -1; | ||
| 562 | + case BarcodeFormat.all: | ||
| 563 | + return 0; | ||
| 564 | + case BarcodeFormat.code128: | ||
| 565 | + return 1; | ||
| 566 | + case BarcodeFormat.code39: | ||
| 567 | + return 2; | ||
| 568 | + case BarcodeFormat.code93: | ||
| 569 | + return 4; | ||
| 570 | + case BarcodeFormat.codebar: | ||
| 571 | + return 8; | ||
| 572 | + case BarcodeFormat.dataMatrix: | ||
| 573 | + return 16; | ||
| 574 | + case BarcodeFormat.ean13: | ||
| 575 | + return 32; | ||
| 576 | + case BarcodeFormat.ean8: | ||
| 577 | + return 64; | ||
| 578 | + case BarcodeFormat.itf: | ||
| 579 | + return 128; | ||
| 580 | + case BarcodeFormat.qrCode: | ||
| 581 | + return 256; | ||
| 582 | + case BarcodeFormat.upcA: | ||
| 583 | + return 512; | ||
| 584 | + case BarcodeFormat.upcE: | ||
| 585 | + return 1024; | ||
| 586 | + case BarcodeFormat.pdf417: | ||
| 587 | + return 2048; | ||
| 588 | + case BarcodeFormat.aztec: | ||
| 589 | + return 4096; | ||
| 590 | + } | ||
| 591 | + } | ||
| 592 | + | ||
| 593 | +} | ||
| 594 | + | ||
| 556 | /// Address type constants. | 595 | /// Address type constants. |
| 557 | enum AddressType { | 596 | enum AddressType { |
| 558 | /// Unknown address type. | 597 | /// Unknown address type. |
-
Please register or login to post a comment