Julian Steenbakker

imp: add docs, update flutter side to match native code.

1 -## NEXT 1 +## 3.0.0-beta.2
2 Breaking changes: 2 Breaking changes:
  3 +* The arguments parameter of onDetect is removed. The data is now returned by the onStart callback
  4 +in the MobileScanner widget.
  5 +* allowDuplicates is removed and replaced by MobileScannerSpeed enum.
  6 +* onPermissionSet in MobileScanner widget is deprecated and will be removed. Use the onPermissionSet
  7 +onPermissionSet callback in MobileScannerController instead.
3 * [iOS] The minimum deployment target is now 11.0 or higher. 8 * [iOS] The minimum deployment target is now 11.0 or higher.
  9 +
  10 +Features:
  11 +* The returnImage is working for both iOS and Android. You can enable it in the MobileScannerController.
  12 +The image will be returned in the BarcodeCapture object provided by onDetect.
  13 +* You can now control the DetectionSpeed, as well as the timeout of the DetectionSpeed. For more
  14 +info see the DetectionSpeed documentation. This replaces the allowDuplicates function.
  15 +
  16 +Other improvements:
  17 +* Both the [iOS] and [Android] codebases have been refactored completely.
4 * [iOS] Updated POD dependencies 18 * [iOS] Updated POD dependencies
5 19
6 ## 3.0.0-beta.1 20 ## 3.0.0-beta.1
@@ -19,6 +19,12 @@ class _BarcodeListScannerWithControllerState @@ -19,6 +19,12 @@ class _BarcodeListScannerWithControllerState
19 torchEnabled: true, 19 torchEnabled: true,
20 // formats: [BarcodeFormat.qrCode] 20 // formats: [BarcodeFormat.qrCode]
21 // facing: CameraFacing.front, 21 // facing: CameraFacing.front,
  22 + onPermissionSet: (hasPermission) {
  23 + // Do something with permission callback
  24 + },
  25 + // detectionSpeed: DetectionSpeed.normal
  26 + // detectionTimeoutMs: 1000,
  27 + // returnImage: false,
22 ); 28 );
23 29
24 bool isStarted = true; 30 bool isStarted = true;
@@ -34,16 +40,18 @@ class _BarcodeListScannerWithControllerState @@ -34,16 +40,18 @@ class _BarcodeListScannerWithControllerState
34 MobileScanner( 40 MobileScanner(
35 controller: controller, 41 controller: controller,
36 fit: BoxFit.contain, 42 fit: BoxFit.contain,
37 - // allowDuplicates: true,  
38 // controller: MobileScannerController( 43 // controller: MobileScannerController(
39 // torchEnabled: true, 44 // torchEnabled: true,
40 // facing: CameraFacing.front, 45 // facing: CameraFacing.front,
41 // ), 46 // ),
42 - onDetect: (barcodeCapture, arguments) { 47 + onDetect: (barcodeCapture) {
43 setState(() { 48 setState(() {
44 this.barcodeCapture = barcodeCapture; 49 this.barcodeCapture = barcodeCapture;
45 }); 50 });
46 }, 51 },
  52 + onStart: (arguments) {
  53 + // Do something with start arguments
  54 + },
47 ), 55 ),
48 Align( 56 Align(
49 alignment: Alignment.bottomCenter, 57 alignment: Alignment.bottomCenter,
@@ -16,9 +16,15 @@ class _BarcodeScannerWithControllerState @@ -16,9 +16,15 @@ class _BarcodeScannerWithControllerState
16 BarcodeCapture? barcode; 16 BarcodeCapture? barcode;
17 17
18 MobileScannerController controller = MobileScannerController( 18 MobileScannerController controller = MobileScannerController(
19 - torchEnabled: true, detectionSpeed: DetectionSpeed.unrestricted, 19 + torchEnabled: true,
20 // formats: [BarcodeFormat.qrCode] 20 // formats: [BarcodeFormat.qrCode]
21 // facing: CameraFacing.front, 21 // facing: CameraFacing.front,
  22 + onPermissionSet: (hasPermission) {
  23 + // Do something with permission callback
  24 + },
  25 + // detectionSpeed: DetectionSpeed.normal
  26 + // detectionTimeoutMs: 1000,
  27 + // returnImage: false,
22 ); 28 );
23 29
24 bool isStarted = true; 30 bool isStarted = true;
@@ -34,12 +40,11 @@ class _BarcodeScannerWithControllerState @@ -34,12 +40,11 @@ class _BarcodeScannerWithControllerState
34 MobileScanner( 40 MobileScanner(
35 controller: controller, 41 controller: controller,
36 fit: BoxFit.contain, 42 fit: BoxFit.contain,
37 - // allowDuplicates: true,  
38 // controller: MobileScannerController( 43 // controller: MobileScannerController(
39 // torchEnabled: true, 44 // torchEnabled: true,
40 // facing: CameraFacing.front, 45 // facing: CameraFacing.front,
41 // ), 46 // ),
42 - onDetect: (barcode, args) { 47 + onDetect: (barcode) {
43 setState(() { 48 setState(() {
44 this.barcode = barcode; 49 this.barcode = barcode;
45 }); 50 });
@@ -18,10 +18,15 @@ class _BarcodeScannerReturningImageState @@ -18,10 +18,15 @@ class _BarcodeScannerReturningImageState
18 MobileScannerArguments? arguments; 18 MobileScannerArguments? arguments;
19 19
20 MobileScannerController controller = MobileScannerController( 20 MobileScannerController controller = MobileScannerController(
21 - // torchEnabled: true,  
22 - returnImage: true, 21 + torchEnabled: true,
23 // formats: [BarcodeFormat.qrCode] 22 // formats: [BarcodeFormat.qrCode]
24 // facing: CameraFacing.front, 23 // facing: CameraFacing.front,
  24 + onPermissionSet: (hasPermission) {
  25 + // Do something with permission callback
  26 + },
  27 + // detectionSpeed: DetectionSpeed.normal
  28 + // detectionTimeoutMs: 1000,
  29 + returnImage: true,
25 ); 30 );
26 31
27 bool isStarted = true; 32 bool isStarted = true;
@@ -29,15 +34,10 @@ class _BarcodeScannerReturningImageState @@ -29,15 +34,10 @@ class _BarcodeScannerReturningImageState
29 @override 34 @override
30 Widget build(BuildContext context) { 35 Widget build(BuildContext context) {
31 return Scaffold( 36 return Scaffold(
32 - backgroundColor: Colors.black,  
33 - body: Builder(  
34 - builder: (context) {  
35 - return Column( 37 + body: SafeArea(
  38 + child: Column(
36 children: [ 39 children: [
37 - Container(  
38 - color: Colors.blueGrey,  
39 - width: double.infinity,  
40 - height: 0.33 * MediaQuery.of(context).size.height, 40 + Expanded(
41 child: barcode?.image != null 41 child: barcode?.image != null
42 ? Transform.rotate( 42 ? Transform.rotate(
43 angle: 90 * pi / 180, 43 angle: 90 * pi / 180,
@@ -47,31 +47,27 @@ class _BarcodeScannerReturningImageState @@ -47,31 +47,27 @@ class _BarcodeScannerReturningImageState
47 fit: BoxFit.contain, 47 fit: BoxFit.contain,
48 ), 48 ),
49 ) 49 )
50 - : const ColoredBox(  
51 - color: Colors.white,  
52 - child: Center( 50 + : const Center(
53 child: Text( 51 child: Text(
54 'Your scanned barcode will appear here!', 52 'Your scanned barcode will appear here!',
55 ), 53 ),
56 ), 54 ),
57 ), 55 ),
58 - ),  
59 - Container(  
60 - height: 0.66 * MediaQuery.of(context).size.height, 56 + Expanded(
  57 + flex: 2,
  58 + child: ColoredBox(
61 color: Colors.grey, 59 color: Colors.grey,
62 child: Stack( 60 child: Stack(
63 children: [ 61 children: [
64 MobileScanner( 62 MobileScanner(
65 controller: controller, 63 controller: controller,
66 fit: BoxFit.contain, 64 fit: BoxFit.contain,
67 - // allowDuplicates: true,  
68 // controller: MobileScannerController( 65 // controller: MobileScannerController(
69 // torchEnabled: true, 66 // torchEnabled: true,
70 // facing: CameraFacing.front, 67 // facing: CameraFacing.front,
71 // ), 68 // ),
72 - onDetect: (barcode, arguments) { 69 + onDetect: (barcode) {
73 setState(() { 70 setState(() {
74 - this.arguments = arguments;  
75 this.barcode = barcode; 71 this.barcode = barcode;
76 }); 72 });
77 }, 73 },
@@ -169,10 +165,9 @@ class _BarcodeScannerReturningImageState @@ -169,10 +165,9 @@ class _BarcodeScannerReturningImageState
169 ], 165 ],
170 ), 166 ),
171 ), 167 ),
  168 + ),
172 ], 169 ],
173 - );  
174 - },  
175 ), 170 ),
176 - ); 171 + ),);
177 } 172 }
178 } 173 }
@@ -24,8 +24,7 @@ class _BarcodeScannerWithoutControllerState @@ -24,8 +24,7 @@ class _BarcodeScannerWithoutControllerState
24 children: [ 24 children: [
25 MobileScanner( 25 MobileScanner(
26 fit: BoxFit.contain, 26 fit: BoxFit.contain,
27 - // allowDuplicates: false,  
28 - onDetect: (capture, arguments) { 27 + onDetect: (capture) {
29 setState(() { 28 setState(() {
30 this.capture = capture; 29 this.capture = capture;
31 }); 30 });
1 library mobile_scanner; 1 library mobile_scanner;
2 2
3 -export 'src/barcode.dart';  
4 -export 'src/barcode_capture.dart';  
5 export 'src/enums/camera_facing.dart'; 3 export 'src/enums/camera_facing.dart';
6 export 'src/enums/detection_speed.dart'; 4 export 'src/enums/detection_speed.dart';
7 export 'src/enums/mobile_scanner_state.dart'; 5 export 'src/enums/mobile_scanner_state.dart';
8 export 'src/enums/ratio.dart'; 6 export 'src/enums/ratio.dart';
9 export 'src/enums/torch_state.dart'; 7 export 'src/enums/torch_state.dart';
10 export 'src/mobile_scanner.dart'; 8 export 'src/mobile_scanner.dart';
11 -export 'src/mobile_scanner_arguments.dart';  
12 export 'src/mobile_scanner_controller.dart'; 9 export 'src/mobile_scanner_controller.dart';
  10 +export 'src/objects/barcode.dart';
  11 +export 'src/objects/barcode_capture.dart';
  12 +export 'src/objects/mobile_scanner_arguments.dart';
@@ -2,11 +2,19 @@ @@ -2,11 +2,19 @@
2 enum DetectionSpeed { 2 enum DetectionSpeed {
3 /// The scanner will only scan a barcode once, and never again until another 3 /// The scanner will only scan a barcode once, and never again until another
4 /// barcode has been scanned. 4 /// barcode has been scanned.
  5 + ///
  6 + /// NOTE: This mode does analyze every frame in order to check if the value
  7 + /// has changed.
5 noDuplicates, 8 noDuplicates,
6 9
7 - /// The barcode scanner will wait 10 + /// The barcode scanner will scan one barcode, and wait 250 Miliseconds before
  11 + /// scanning again. This will prevent memory issues on older devices.
  12 + ///
  13 + /// You can change the timeout duration with [detectionTimeout] parameter.
8 normal, 14 normal,
9 15
10 - /// Back facing camera. 16 + /// Let the scanner detect barcodes without restriction.
  17 + ///
  18 + /// NOTE: This can cause memory issues with older devices.
11 unrestricted, 19 unrestricted,
12 } 20 }
1 -enum MobileScannerState { undetermined, authorized, denied } 1 +/// The authorization state of the scanner.
  2 +enum MobileScannerState {
  3 + /// The scanner has yet to request weather it is [authorized] or [denied]
  4 + undetermined,
  5 +
  6 + /// The scanner has the required permissions.
  7 + authorized,
  8 +
  9 + /// The user denied the required permissions.
  10 + denied
  11 +}
1 -enum Ratio { ratio_4_3, ratio_16_9 } 1 +// This enum is not used yet
  2 +// enum Ratio { ratio_4_3, ratio_16_9 }
1 import 'package:flutter/foundation.dart'; 1 import 'package:flutter/foundation.dart';
2 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
3 -import 'package:mobile_scanner/src/barcode_capture.dart';  
4 -import 'package:mobile_scanner/src/mobile_scanner_arguments.dart';  
5 import 'package:mobile_scanner/src/mobile_scanner_controller.dart'; 3 import 'package:mobile_scanner/src/mobile_scanner_controller.dart';
  4 +import 'package:mobile_scanner/src/objects/barcode_capture.dart';
  5 +import 'package:mobile_scanner/src/objects/mobile_scanner_arguments.dart';
  6 +
  7 +typedef MobileScannerCallback = void Function(BarcodeCapture barcodes);
  8 +typedef MobileScannerArgumentsCallback = void Function(
  9 + MobileScannerArguments? arguments,
  10 +);
6 11
7 /// A widget showing a live camera preview. 12 /// A widget showing a live camera preview.
8 class MobileScanner extends StatefulWidget { 13 class MobileScanner extends StatefulWidget {
@@ -10,14 +15,21 @@ class MobileScanner extends StatefulWidget { @@ -10,14 +15,21 @@ class MobileScanner extends StatefulWidget {
10 final MobileScannerController? controller; 15 final MobileScannerController? controller;
11 16
12 /// Calls the provided [onPermissionSet] callback when the permission is set. 17 /// Calls the provided [onPermissionSet] callback when the permission is set.
  18 + // @Deprecated('Use the [onPermissionSet] paremeter in the [MobileScannerController] instead.')
  19 + // ignore: deprecated_consistency
13 final Function(bool permissionGranted)? onPermissionSet; 20 final Function(bool permissionGranted)? onPermissionSet;
14 21
15 /// Function that gets called when a Barcode is detected. 22 /// Function that gets called when a Barcode is detected.
16 /// 23 ///
17 /// [barcode] The barcode object with all information about the scanned code. 24 /// [barcode] The barcode object with all information about the scanned code.
18 - /// [startArguments] Information about the state of the MobileScanner widget  
19 - final Function(BarcodeCapture capture, MobileScannerArguments? arguments)  
20 - onDetect; 25 + /// [startInternalArguments] Information about the state of the MobileScanner widget
  26 + final MobileScannerCallback onDetect;
  27 +
  28 + /// Function that gets called when the scanner is started.
  29 + ///
  30 + /// [arguments] The start arguments of the scanner. This contains the size of
  31 + /// the scanner which can be used to draw a box over the scanner.
  32 + final MobileScannerArgumentsCallback? onStart;
21 33
22 /// Handles how the widget should fit the screen. 34 /// Handles how the widget should fit the screen.
23 final BoxFit fit; 35 final BoxFit fit;
@@ -29,9 +41,11 @@ class MobileScanner extends StatefulWidget { @@ -29,9 +41,11 @@ class MobileScanner extends StatefulWidget {
29 const MobileScanner({ 41 const MobileScanner({
30 super.key, 42 super.key,
31 required this.onDetect, 43 required this.onDetect,
  44 + this.onStart,
32 this.controller, 45 this.controller,
33 this.autoResume = true, 46 this.autoResume = true,
34 this.fit = BoxFit.cover, 47 this.fit = BoxFit.cover,
  48 + @Deprecated('Use the [onPermissionSet] paremeter in the [MobileScannerController] instead.')
35 this.onPermissionSet, 49 this.onPermissionSet,
36 }); 50 });
37 51
@@ -49,7 +63,14 @@ class _MobileScannerState extends State<MobileScanner> @@ -49,7 +63,14 @@ class _MobileScannerState extends State<MobileScanner>
49 WidgetsBinding.instance.addObserver(this); 63 WidgetsBinding.instance.addObserver(this);
50 controller = widget.controller ?? 64 controller = widget.controller ??
51 MobileScannerController(onPermissionSet: widget.onPermissionSet); 65 MobileScannerController(onPermissionSet: widget.onPermissionSet);
52 - if (!controller.isStarting) controller.start(); 66 + if (!controller.isStarting) {
  67 + _startScanner();
  68 + }
  69 + }
  70 +
  71 + Future<void> _startScanner() async {
  72 + final arguments = await controller.start();
  73 + widget.onStart?.call(arguments);
53 } 74 }
54 75
55 bool resumeFromBackground = false; 76 bool resumeFromBackground = false;
@@ -64,7 +85,7 @@ class _MobileScannerState extends State<MobileScanner> @@ -64,7 +85,7 @@ class _MobileScannerState extends State<MobileScanner>
64 switch (state) { 85 switch (state) {
65 case AppLifecycleState.resumed: 86 case AppLifecycleState.resumed:
66 resumeFromBackground = false; 87 resumeFromBackground = false;
67 - controller.start(); 88 + _startScanner();
68 break; 89 break;
69 case AppLifecycleState.paused: 90 case AppLifecycleState.paused:
70 resumeFromBackground = true; 91 resumeFromBackground = true;
@@ -87,7 +108,7 @@ class _MobileScannerState extends State<MobileScanner> @@ -87,7 +108,7 @@ class _MobileScannerState extends State<MobileScanner>
87 return const ColoredBox(color: Colors.black); 108 return const ColoredBox(color: Colors.black);
88 } else { 109 } else {
89 controller.barcodes.listen((barcode) { 110 controller.barcodes.listen((barcode) {
90 - widget.onDetect(barcode, value! as MobileScannerArguments); 111 + widget.onDetect(barcode);
91 }); 112 });
92 return ClipRect( 113 return ClipRect(
93 child: SizedBox( 114 child: SizedBox(
@@ -30,7 +30,8 @@ class MobileScannerController { @@ -30,7 +30,8 @@ class MobileScannerController {
30 .listen((data) => _handleEvent(data as Map)); 30 .listen((data) => _handleEvent(data as Map));
31 } 31 }
32 32
33 - //Must be static to keep the same value on new instances 33 + /// The hashcode of the controller to check if the correct object is mounted.
  34 + /// Must be static to keep the same value on new instances
34 static int? controllerHashcode; 35 static int? controllerHashcode;
35 36
36 /// Select which camera should be used. 37 /// Select which camera should be used.
@@ -56,6 +57,11 @@ class MobileScannerController { @@ -56,6 +57,11 @@ class MobileScannerController {
56 /// WARNING: DetectionSpeed.unrestricted can cause memory issues on some devices 57 /// WARNING: DetectionSpeed.unrestricted can cause memory issues on some devices
57 final DetectionSpeed detectionSpeed; 58 final DetectionSpeed detectionSpeed;
58 59
  60 + /// Sets the timeout of scanner.
  61 + /// The timeout is set in miliseconds.
  62 + ///
  63 + /// NOTE: The timeout only works if the [detectionSpeed] is set to
  64 + /// [DetectionSpeed.normal] (which is the default value).
59 final int detectionTimeoutMs; 65 final int detectionTimeoutMs;
60 66
61 /// Sets the barcode stream 67 /// Sets the barcode stream
@@ -85,6 +91,7 @@ class MobileScannerController { @@ -85,6 +91,7 @@ class MobileScannerController {
85 ValueNotifier(facing); 91 ValueNotifier(facing);
86 92
87 bool isStarting = false; 93 bool isStarting = false;
  94 +
88 bool? _hasTorch; 95 bool? _hasTorch;
89 96
90 /// Set the starting arguments for the camera 97 /// Set the starting arguments for the camera
@@ -113,9 +120,9 @@ class MobileScannerController { @@ -113,9 +120,9 @@ class MobileScannerController {
113 Future<MobileScannerArguments?> start({ 120 Future<MobileScannerArguments?> start({
114 CameraFacing? cameraFacingOverride, 121 CameraFacing? cameraFacingOverride,
115 }) async { 122 }) async {
116 - debugPrint('Hashcode controller: $hashCode');  
117 if (isStarting) { 123 if (isStarting) {
118 debugPrint("Called start() while starting."); 124 debugPrint("Called start() while starting.");
  125 + return null;
119 } 126 }
120 isStarting = true; 127 isStarting = true;
121 128
@@ -152,10 +159,10 @@ class MobileScannerController { @@ -152,10 +159,10 @@ class MobileScannerController {
152 ); 159 );
153 } on PlatformException catch (error) { 160 } on PlatformException catch (error) {
154 debugPrint('${error.code}: ${error.message}'); 161 debugPrint('${error.code}: ${error.message}');
155 - isStarting = false;  
156 if (error.code == "MobileScannerWeb") { 162 if (error.code == "MobileScannerWeb") {
157 onPermissionSet?.call(false); 163 onPermissionSet?.call(false);
158 } 164 }
  165 + isStarting = false;
159 return null; 166 return null;
160 } 167 }
161 168
@@ -172,28 +179,25 @@ class MobileScannerController { @@ -172,28 +179,25 @@ class MobileScannerController {
172 } 179 }
173 180
174 if (kIsWeb) { 181 if (kIsWeb) {
  182 + // If we reach this line, it means camera permission has been granted
175 onPermissionSet?.call( 183 onPermissionSet?.call(
176 true, 184 true,
177 - ); // If we reach this line, it means camera permission has been granted 185 + );
  186 + }
178 187
179 - startArguments.value = MobileScannerArguments(  
180 - webId: startResult['ViewID'] as String?,  
181 - size: Size( 188 + isStarting = false;
  189 + return startArguments.value = MobileScannerArguments(
  190 + size: kIsWeb
  191 + ? Size(
182 startResult['videoWidth'] as double? ?? 0, 192 startResult['videoWidth'] as double? ?? 0,
183 startResult['videoHeight'] as double? ?? 0, 193 startResult['videoHeight'] as double? ?? 0,
184 - ),  
185 - hasTorch: _hasTorch!,  
186 - );  
187 - } else {  
188 - startArguments.value = MobileScannerArguments(  
189 - textureId: startResult['textureId'] as int?,  
190 - size: toSize(startResult['size'] as Map? ?? {}), 194 + )
  195 + : toSize(startResult['size'] as Map? ?? {}),
191 hasTorch: _hasTorch!, 196 hasTorch: _hasTorch!,
  197 + textureId: kIsWeb ? null : startResult['textureId'] as int?,
  198 + webId: kIsWeb ? startResult['ViewID'] as String? : null,
192 ); 199 );
193 } 200 }
194 - isStarting = false;  
195 - return startArguments.value!;  
196 - }  
197 201
198 /// Stops the camera, but does not dispose this controller. 202 /// Stops the camera, but does not dispose this controller.
199 Future<void> stop() async { 203 Future<void> stop() async {
@@ -12,11 +12,6 @@ class Barcode { @@ -12,11 +12,6 @@ class Barcode {
12 /// Returns null if the corner points can not be determined. 12 /// Returns null if the corner points can not be determined.
13 final List<Offset>? corners; 13 final List<Offset>? corners;
14 14
15 - /// Returns raw bytes of the image buffer  
16 - ///  
17 - /// Returns null if the image was not returned  
18 - final Uint8List? image;  
19 -  
20 /// Returns barcode format 15 /// Returns barcode format
21 final BarcodeFormat format; 16 final BarcodeFormat format;
22 17
@@ -79,7 +74,6 @@ class Barcode { @@ -79,7 +74,6 @@ class Barcode {
79 74
80 Barcode({ 75 Barcode({
81 this.corners, 76 this.corners,
82 - this.image,  
83 this.format = BarcodeFormat.ean13, 77 this.format = BarcodeFormat.ean13,
84 this.rawBytes, 78 this.rawBytes,
85 this.type = BarcodeType.text, 79 this.type = BarcodeType.text,
@@ -97,7 +91,7 @@ class Barcode { @@ -97,7 +91,7 @@ class Barcode {
97 }); 91 });
98 92
99 /// Create a [Barcode] from native data. 93 /// Create a [Barcode] from native data.
100 - Barcode.fromNative(Map data, {this.image}) 94 + Barcode.fromNative(Map data)
101 : corners = toCorners(data['corners'] as List?), 95 : corners = toCorners(data['corners'] as List?),
102 format = toFormat(data['format'] as int), 96 format = toFormat(data['format'] as int),
103 rawBytes = data['rawBytes'] as Uint8List?, 97 rawBytes = data['rawBytes'] as Uint8List?,
1 import 'dart:typed_data'; 1 import 'dart:typed_data';
2 2
3 -import 'package:mobile_scanner/src/barcode.dart'; 3 +import 'package:mobile_scanner/src/objects/barcode.dart';
4 4
  5 +/// The return object after a frame is scanned.
  6 +///
  7 +/// [barcodes] A list with barcodes. A scanned frame can contain multiple
  8 +/// barcodes.
  9 +/// [image] If enabled, an image of the scanned frame.
5 class BarcodeCapture { 10 class BarcodeCapture {
6 - List<Barcode> barcodes;  
7 - Uint8List? image; 11 + final List<Barcode> barcodes;
  12 +
  13 + final Uint8List? image;
8 14
9 BarcodeCapture({ 15 BarcodeCapture({
10 required this.barcodes, 16 required this.barcodes,
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 2
3 -/// Camera args for [CameraView]. 3 +/// The start arguments of the scanner.
4 class MobileScannerArguments { 4 class MobileScannerArguments {
5 - /// The texture id.  
6 - final int? textureId;  
7 -  
8 - /// Size of the texture. 5 + /// The output size of the camera.
  6 + /// This value can be used to draw a box in the image.
9 final Size size; 7 final Size size;
10 8
  9 + /// A bool which is true if the device has a torch.
11 final bool hasTorch; 10 final bool hasTorch;
12 11
  12 + /// The texture id of the capture used internally.
  13 + final int? textureId;
  14 +
  15 + /// The texture id of the capture used internally if device is web.
13 final String? webId; 16 final String? webId;
14 17
15 - /// Create a [MobileScannerArguments].  
16 MobileScannerArguments({ 18 MobileScannerArguments({
17 - this.textureId,  
18 required this.size, 19 required this.size,
19 required this.hasTorch, 20 required this.hasTorch,
  21 + this.textureId,
20 this.webId, 22 this.webId,
21 }); 23 });
22 } 24 }
1 name: mobile_scanner 1 name: mobile_scanner
2 description: A universal barcode and QR code scanner for Flutter based on MLKit. Uses CameraX on Android, AVFoundation on iOS and Apple Vision & AVFoundation on macOS. 2 description: A universal barcode and QR code scanner for Flutter based on MLKit. Uses CameraX on Android, AVFoundation on iOS and Apple Vision & AVFoundation on macOS.
3 -version: 3.0.0-beta.1 3 +version: 3.0.0-beta.2
4 repository: https://github.com/juliansteenbakker/mobile_scanner 4 repository: https://github.com/juliansteenbakker/mobile_scanner
5 5
6 environment: 6 environment: