@@ -3,48 +3,89 @@ import 'package:zxing2/qrcode.dart';
3
3
4
4
/// QR code extensions on [Image] .
5
5
extension ImageQrScanning on Image {
6
- /// Attempts to find and decode a QR code within this [Image] .
7
- QrCode readQrCode () {
8
- final rgbLuminanceSource = RGBLuminanceSource (
9
- width,
10
- height,
11
- convert (numChannels: 4 ) //
12
- .getBytes (order: ChannelOrder .abgr)
13
- .buffer
14
- .asInt32List (),
15
- );
6
+ /// Returns the first QR code found within this [Image] , or `null` if no QR code is found.
7
+ ///
8
+ /// If there are multiple QR codes in the image, it returns the first one it finds
9
+ /// from top to bottom.
10
+ QrCode ? readQrCode () {
11
+ return _readQrCode (this );
12
+ }
16
13
17
- try {
18
- final binarizer = HybridBinarizer (rgbLuminanceSource);
19
- final binaryBitmap = BinaryBitmap (binarizer);
20
- return QRCodeReader ().decode (binaryBitmap);
21
- } on ReaderException {
22
- // We failed to find a QR code when looking for a dark QR code
23
- // on a light background. Ignore this exception and try to look
24
- // for inverted colors.
25
- }
14
+ /// Attempts to find and decode all QR codes within this [Image] .
15
+ List <QrCode > readAllQrCodes () {
16
+ final qrCodes = < QrCode > [];
17
+
18
+ final image = clone ();
19
+
20
+ // Keep looking for QR codes until we can't find anymore.
21
+ bool keepSearching = true ;
22
+ while (keepSearching) {
23
+ final qrcode = _readQrCode (image);
24
+ if (qrcode == null ) {
25
+ keepSearching = false ;
26
+ continue ;
27
+ }
28
+
29
+ qrCodes.add (qrcode);
30
+
31
+ /// Extract the rectangles from the edge points.
32
+ final bottomLeftRectangle = qrcode.resultPoints[0 ];
33
+ final topLeftRectangle = qrcode.resultPoints[1 ];
34
+ final topRightRectangle = qrcode.resultPoints[2 ];
35
+
36
+ final top = topRightRectangle.y.truncate ();
37
+ final left = topLeftRectangle.x.truncate ();
38
+ final right = topRightRectangle.x.truncate ();
39
+ final bottom = bottomLeftRectangle.y.truncate ();
26
40
27
- try {
28
- final binarizer = HybridBinarizer (
29
- InvertedLuminanceSource (
30
- rgbLuminanceSource,
31
- ),
41
+ // Fill the QRCode region with black color to try to read other QR Codes.
42
+ fillRect (
43
+ image,
44
+ x1: left,
45
+ y1: top,
46
+ x2: right,
47
+ y2: bottom,
48
+ color: ColorRgb8 (0 , 0 , 0 ),
32
49
);
33
- final binaryBitmap = BinaryBitmap (binarizer);
34
- return QRCodeReader ().decode (binaryBitmap);
35
- } on ReaderException catch (exception) {
36
- throw CouldNotReadQrCodeException (exception);
37
50
}
51
+
52
+ return qrCodes;
38
53
}
39
54
}
40
55
41
- typedef QrCode = Result ;
42
-
43
- class CouldNotReadQrCodeException implements Exception {
44
- const CouldNotReadQrCodeException ([this .rootCause]);
56
+ QrCode ? _readQrCode (Image image) {
57
+ final rgbLuminanceSource = RGBLuminanceSource (
58
+ image.width,
59
+ image.height,
60
+ image
61
+ .convert (numChannels: 4 ) //
62
+ .getBytes (order: ChannelOrder .abgr)
63
+ .buffer
64
+ .asInt32List (),
65
+ );
45
66
46
- final Exception ? rootCause;
67
+ try {
68
+ final binarizer = HybridBinarizer (rgbLuminanceSource);
69
+ final binaryBitmap = BinaryBitmap (binarizer);
70
+ return QRCodeReader ().decode (binaryBitmap);
71
+ } on ReaderException {
72
+ // We failed to find a QR code when looking for a dark QR code
73
+ // on a light background. Ignore this exception and try to look
74
+ // for inverted colors.
75
+ }
47
76
48
- @override
49
- String toString () => "CouldNotReadQrCodeException" ;
77
+ try {
78
+ final binarizer = HybridBinarizer (
79
+ InvertedLuminanceSource (
80
+ rgbLuminanceSource,
81
+ ),
82
+ );
83
+ final binaryBitmap = BinaryBitmap (binarizer);
84
+ return QRCodeReader ().decode (binaryBitmap);
85
+ } on ReaderException {
86
+ // We didn't find a QR code in the image.
87
+ return null ;
88
+ }
50
89
}
90
+
91
+ typedef QrCode = Result ;
0 commit comments