Showing
3 changed files
with
49 additions
and
21 deletions
| @@ -25,14 +25,10 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist> { | @@ -25,14 +25,10 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist> { | ||
| 25 | final _mobileScannerController = MobileScannerController( | 25 | final _mobileScannerController = MobileScannerController( |
| 26 | // The controller is started from the initState method. | 26 | // The controller is started from the initState method. |
| 27 | autoStart: false, | 27 | autoStart: false, |
| 28 | - // The know the placing of the barcodes, we need to know the size of the | ||
| 29 | - // canvas they are placed on. Unfortunately the only known reliable way | ||
| 30 | - // to get the dimensions, is to receive the complete image from the native | ||
| 31 | - // side. | ||
| 32 | - // https://github.com/juliansteenbakker/mobile_scanner/issues/1183 | ||
| 33 | - returnImage: true, | ||
| 34 | ); | 28 | ); |
| 35 | 29 | ||
| 30 | + final orientation = DeviceOrientation.portraitUp; | ||
| 31 | + | ||
| 36 | // On this subscription the barcodes are received. | 32 | // On this subscription the barcodes are received. |
| 37 | StreamSubscription<Object?>? _subscription; | 33 | StreamSubscription<Object?>? _subscription; |
| 38 | 34 | ||
| @@ -45,17 +41,8 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist> { | @@ -45,17 +41,8 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist> { | ||
| 45 | 41 | ||
| 46 | @override | 42 | @override |
| 47 | void initState() { | 43 | void initState() { |
| 48 | - // Enable and disable scanning on the native side, so we don't get a stream | ||
| 49 | - // of images when not needed. This also improves the behavior (false | ||
| 50 | - // positives) when the user switches quickly to another barcode after | ||
| 51 | - // enabling the scanner by releasing the finger. | ||
| 52 | - _scannerEnabled.addListener(() { | ||
| 53 | - _scannerEnabled.value | ||
| 54 | - ? _mobileScannerController.updateScanWindow(null) | ||
| 55 | - : _mobileScannerController.updateScanWindow(Rect.zero); | ||
| 56 | - }); | ||
| 57 | // Lock to portrait (may not work on iPad with multitasking). | 44 | // Lock to portrait (may not work on iPad with multitasking). |
| 58 | - SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); | 45 | + SystemChrome.setPreferredOrientations([orientation]); |
| 59 | // Get a stream subscription and listen to received barcodes. | 46 | // Get a stream subscription and listen to received barcodes. |
| 60 | _subscription = _mobileScannerController.barcodes.listen(_handleBarcodes); | 47 | _subscription = _mobileScannerController.barcodes.listen(_handleBarcodes); |
| 61 | super.initState(); | 48 | super.initState(); |
| @@ -83,7 +70,7 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist> { | @@ -83,7 +70,7 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist> { | ||
| 83 | if (!_scannerEnabled.value || _validBarcodeFound) { | 70 | if (!_scannerEnabled.value || _validBarcodeFound) { |
| 84 | return; | 71 | return; |
| 85 | } | 72 | } |
| 86 | - final barcode = findBarcodeAtCenter(barcodeCapture); | 73 | + final barcode = findBarcodeAtCenter(barcodeCapture, orientation); |
| 87 | if (barcode != null) { | 74 | if (barcode != null) { |
| 88 | _validBarcodeFound = true; | 75 | _validBarcodeFound = true; |
| 89 | Navigator.of(context).pop(barcode); | 76 | Navigator.of(context).pop(barcode); |
| 1 | -import 'package:flutter/material.dart'; | 1 | +import 'package:flutter/services.dart'; |
| 2 | import 'package:mobile_scanner/mobile_scanner.dart'; | 2 | import 'package:mobile_scanner/mobile_scanner.dart'; |
| 3 | +import 'package:mobile_scanner_example/picklist/classes/fix_coordinate_space.dart'; | ||
| 3 | 4 | ||
| 4 | /// This function finds the barcode that touches the center of the | 5 | /// This function finds the barcode that touches the center of the |
| 5 | /// image. If no barcode is found that touches the center, null is returned. | 6 | /// image. If no barcode is found that touches the center, null is returned. |
| 6 | /// See [_BarcodeScannerPicklistState] and the returnImage option for more info. | 7 | /// See [_BarcodeScannerPicklistState] and the returnImage option for more info. |
| 7 | /// | 8 | /// |
| 8 | /// https://github.com/juliansteenbakker/mobile_scanner/issues/1183 | 9 | /// https://github.com/juliansteenbakker/mobile_scanner/issues/1183 |
| 9 | -Barcode? findBarcodeAtCenter(BarcodeCapture barcodeCapture) { | ||
| 10 | - final imageSize = barcodeCapture.size; | 10 | +Barcode? findBarcodeAtCenter( |
| 11 | + BarcodeCapture barcodeCapture, | ||
| 12 | + DeviceOrientation orientation, | ||
| 13 | +) { | ||
| 14 | + final imageSize = fixPortraitLandscape(barcodeCapture.size, orientation); | ||
| 11 | for (final barcode in barcodeCapture.barcodes) { | 15 | for (final barcode in barcodeCapture.barcodes) { |
| 16 | + final corners = fixCorners(barcode.corners); | ||
| 12 | if (_isPolygonTouchingTheCenter( | 17 | if (_isPolygonTouchingTheCenter( |
| 13 | imageSize: imageSize, | 18 | imageSize: imageSize, |
| 14 | - polygon: barcode.corners, | 19 | + polygon: corners, |
| 15 | )) { | 20 | )) { |
| 16 | return barcode; | 21 | return barcode; |
| 17 | } | 22 | } |
| 1 | +import 'package:flutter/services.dart'; | ||
| 2 | + | ||
| 3 | +Size fixPortraitLandscape( | ||
| 4 | + Size imageSize, | ||
| 5 | + DeviceOrientation orientation, | ||
| 6 | +) { | ||
| 7 | + switch (orientation) { | ||
| 8 | + case DeviceOrientation.portraitUp: | ||
| 9 | + case DeviceOrientation.portraitDown: | ||
| 10 | + return Size(imageSize.shortestSide, imageSize.longestSide); | ||
| 11 | + case DeviceOrientation.landscapeLeft: | ||
| 12 | + case DeviceOrientation.landscapeRight: | ||
| 13 | + return Size(imageSize.longestSide, imageSize.shortestSide); | ||
| 14 | + } | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +List<Offset> fixCorners(List<Offset> corners) { | ||
| 18 | + // Clone the original list to avoid side-effects | ||
| 19 | + final sorted = List<Offset>.from(corners); | ||
| 20 | + | ||
| 21 | + sorted.sort((a, b) { | ||
| 22 | + // Prioritize y-axis (dy), and within that, the x-axis (dx) | ||
| 23 | + int compare = a.dy.compareTo(b.dy); | ||
| 24 | + if (compare == 0) { | ||
| 25 | + compare = a.dx.compareTo(b.dx); | ||
| 26 | + } | ||
| 27 | + return compare; | ||
| 28 | + }); | ||
| 29 | + | ||
| 30 | + final topLeft = sorted.first; // smallest x, smallest y | ||
| 31 | + final topRight = sorted[1]; // larger x, smaller y | ||
| 32 | + final bottomLeft = sorted[2]; // smaller x, larger y | ||
| 33 | + final bottomRight = sorted.last; // larger x, larger y | ||
| 34 | + | ||
| 35 | + return [topLeft, topRight, bottomRight, bottomLeft]; | ||
| 36 | +} |
-
Please register or login to post a comment