From 7647bd3d298c5f3fb62de6db5a31e853c05de35b Mon Sep 17 00:00:00 2001 From: Joshua Hoogstraat <34964599+jhoogstraat@users.noreply.github.com> Date: Mon, 5 Jul 2021 16:04:51 +0200 Subject: [PATCH] Updates readme and overlay fix --- fast_barcode_scanner/CHANGELOG.md | 4 +- fast_barcode_scanner/README.md | 41 +++++++++++-------- .../example/lib/scanner_screen.dart | 4 +- .../lib/src/barcode_camera.dart | 2 +- .../lib/src/camera_controller.dart | 14 +++---- .../lib/src/overlays/material_overlay.dart | 26 ++++++++---- .../material_sensing_painter.dart | 14 +++++-- fast_barcode_scanner/pubspec.yaml | 7 ++-- .../pubspec.yaml | 2 +- 9 files changed, 70 insertions(+), 44 deletions(-) diff --git a/fast_barcode_scanner/CHANGELOG.md b/fast_barcode_scanner/CHANGELOG.md index 6c8eeda6..39a5edde 100644 --- a/fast_barcode_scanner/CHANGELOG.md +++ b/fast_barcode_scanner/CHANGELOG.md @@ -1,9 +1,11 @@ # 2.0.0 + * Added ability to change the scanner configuration while running * Restructured and simplified native code on iOS and Android * Fully implemented error handling * UPC-A is now correctly reported on iOS (EAN-13 with a leading 0 is regarded as UPC-A). -* ... +* Massively improved sample app with controls over all features. +* Updated CameraX and ML Kit to the newest versions ## 1.1.1 diff --git a/fast_barcode_scanner/README.md b/fast_barcode_scanner/README.md index 6f0f63c4..dfde21ec 100644 --- a/fast_barcode_scanner/README.md +++ b/fast_barcode_scanner/README.md @@ -4,14 +4,14 @@ A fast barcode scanner using **MLKit** (and **CameraX**) on Android and **AVFoundation** on iOS. This package leaves the UI up to the user, but rather gives an access to a camera preview. -*Note*: This plugin is still under development, and some APIs might not be available yet. If you have any issues, ideas or recommendendations, don't hesitate to create an issue or pull request on github. I am using this plugin in production myself and will actively develop and maintain it going forward. +*Note*: If you have any issues, ideas or recommendendations, don't hesitate to create an issue or pull request on github. I am using this plugin in production myself and will actively develop and maintain it going forward. -**This plugin required iOS 10.0 and Android sdk version 21 or higher.** +**This plugin required iOS 10.0 and Android sdk version 23 or higher.** ## Installation Add the following line to your **pubspec.yaml**: ```yaml -fast_barcode_scanner: ^1.1.0 +fast_barcode_scanner: ^2.0.0 ``` ### iOS Add the `NSCameraUsageDescription` key to your `ios/Runner/Info.plist`, like so: @@ -21,14 +21,14 @@ Add the `NSCameraUsageDescription` key to your `ios/Runner/Info.plist`, like so: ``` ### Android -Change the minimum Android sdk version to 21 (or higher) in your `android/app/build.gradle` file. +Change the minimum Android sdk version to 23 (or higher) in your `android/app/build.gradle` file. ``` -minSdkVersion 21 +minSdkVersion 23 ``` ## Usage -The barcode scanner consists of two main classes `CameraController` and `BarcodeCamera`. -A full example looks like this: +The barcode scanner consists of two main classes `CameraController` and `BarcodeCamera`, which are further described below. Have a look at the example app to find out how to control and interact with the plugin. +A (almost) minimal example looks like this: ```dart import 'package:fast_barcode_scanner/fast_barcode_scanner.dart'; @@ -63,45 +63,50 @@ class MyScannerScreen extends StatelessWidget { } } ``` -As you can see, there are two overlays in the childrens list. These two are included in the package. `MaterialPreviewOverlay` mimics the official [material barcode scanning example](https://material.io/design/machine-learning/barcode-scanning.html#usage). `BlurPreviewOverlay` blurs the screen when a barcode is detected and unblurs it on resuming. These are normal widget, which are shown above the camera preview. Look at their source code to find out, how to react to events from the barcode scanner. +You don' have to provide all settings yourself, as sensible defaults are set already. +As you can see, there are two overlays in the childrens list. These two are included in the package. `MaterialPreviewOverlay` mimics the official [material barcode scanning example](https://material.io/design/machine-learning/barcode-scanning.html#usage). `BlurPreviewOverlay` blurs the screen when a barcode is detected and unblurs it on resuming. These are normal widget, which are shown above the camera preview (inside a `Stack` widget). If you want to code your own overlay, look at the source code, to find out how to react to events from the barcode scanner. ### CameraController The `CameraController`-singleton manages the camera. It handles all the low level stuff like communicating with native code. It is implemented as a singleton to guarantee that there is always one and the same controller managing the camera. You can access the controller via the `CameraController.instance` attribute. These are the accessible methods: method |Description ----------------|------------------------------------------------- -`initialize` | Initialized the scanner with the provided config -`pauseDetector` | Actively pauses the scanner -`resumeDetector`| Resumes the scanner from the paused state -`toggleTorch` | toggles the torch on and off -`dispose` | Stops and resets the camera on platform level +`initialize` | Initializes the scanner with the provided config +`pauseDetector` | Actively pauses the scanner +`resumeDetector`| Resumes the scanner from the paused state +`toggleTorch` | toggles the torch on and off +`dispose` | Stops and resets the camera on platform level You do not have to call `initialize` yourself, if you use the `BarcodeCamera` widget. +Calling these methods are throwing. For possible error codes have a look at ScannerError.swift or ScannerError.kt. -### CameraState +#### CameraState `CameraController.instance.state` contains the current state of the scanner. -You can use it to build your own overlay. The following information can be accessed: +Use it to build your own overlay. The following information can be accessed: Attribute | Description ----------------|------------------------------------------------- `isInitialized` | Indicated whether the camera is currently initialized `previewConfig` | A `PreviewConfiguration` that is currently used +`scannerConfig` | A `ScannerConfiguration` that is currently used `eventNotifier` | A event notifier to react to init or detecting codes `torchState` | The current state of the torch (on/off) `hasError` | Indicates whether `error` is null or not `error` | Access the error produced last +A `PreviewConfiguration` contains informations about the the dimensions and rotation of the preview and `ScannerConfiguration` holds the settings about how the camera was setup. + ### BarcodeCamera The `BarcodeCamera` is a widget showing a preview of the camera feed. It calls the `CameraController` in the background for initialization and configuration of the barcode camera. -An overview of all possible configurations (either passed to `BarcodeCamera` or `CameraController.initialize`): +It allows to configurate the scanner. A `ScannerConfiguration` is then generated and passed to native code, which in turn produces a `PreviewConfiguration`. You can find both in the `CameraController.instance.state` attribute. A full overview of all parameters that can be passed to `BarcodeCamera`: Attribute |Description -------------|------------------------------------------- `types` | See code types to scan (see `BarcodeType`) -`mode` | Whether to pause the camera on detection `resolution` | The resolution of the camera feed `framerate` | The framerate of the camera feed `position` | Choose between back and front camera +`mode` | Whether to pause the camera on detection `onScan` | The callback when a barcode is scanned -`children` | Widgets to display on top of the preview‚ +`children` | Widgets to display on top of the preview diff --git a/fast_barcode_scanner/example/lib/scanner_screen.dart b/fast_barcode_scanner/example/lib/scanner_screen.dart index 553bb567..b2cd6e75 100644 --- a/fast_barcode_scanner/example/lib/scanner_screen.dart +++ b/fast_barcode_scanner/example/lib/scanner_screen.dart @@ -70,8 +70,8 @@ class _ScannerScreenState extends State { position: CameraPosition.back, onScan: (code) => codeStream.add(code), children: const [ - MaterialPreviewOverlay(animateDetection: false), - BlurPreviewOverlay() + MaterialPreviewOverlay(showSensing: true), + // BlurPreviewOverlay() ], ), bottomSheet: SafeArea( diff --git a/fast_barcode_scanner/lib/src/barcode_camera.dart b/fast_barcode_scanner/lib/src/barcode_camera.dart index dec2fadf..68e0b259 100644 --- a/fast_barcode_scanner/lib/src/barcode_camera.dart +++ b/fast_barcode_scanner/lib/src/barcode_camera.dart @@ -53,7 +53,7 @@ class BarcodeCameraState extends State { CameraController.instance .initialize(widget.types, widget.resolution, widget.framerate, - widget.mode, widget.position, widget.onScan) + widget.position, widget.mode, widget.onScan) .whenComplete(() => setState(() => _opacity = 1.0)); } diff --git a/fast_barcode_scanner/lib/src/camera_controller.dart b/fast_barcode_scanner/lib/src/camera_controller.dart index 5cfac4e1..234882d3 100644 --- a/fast_barcode_scanner/lib/src/camera_controller.dart +++ b/fast_barcode_scanner/lib/src/camera_controller.dart @@ -10,8 +10,8 @@ class ScannerConfiguration { this.types, this.resolution, this.framerate, - this.detectionMode, this.position, + this.detectionMode, ); /// The types the scanner should look out for. @@ -31,12 +31,12 @@ class ScannerConfiguration { /// than necessary. final Framerate framerate; - /// Determines how the camera reacts to detected barcodes. - final DetectionMode detectionMode; - /// The physical position of the camera being used. final CameraPosition position; + /// Determines how the camera reacts to detected barcodes. + final DetectionMode detectionMode; + ScannerConfiguration copyWith({ List? types, Resolution? resolution, @@ -48,8 +48,8 @@ class ScannerConfiguration { types ?? this.types, resolution ?? this.resolution, framerate ?? this.framerate, - detectionMode ?? this.detectionMode, position ?? this.position, + detectionMode ?? this.detectionMode, ); } } @@ -100,8 +100,8 @@ class CameraController { List types, Resolution resolution, Framerate framerate, - DetectionMode detectionMode, CameraPosition position, + DetectionMode detectionMode, void Function(Barcode)? onScan) async { state.eventNotifier.value = CameraEvent.init; @@ -117,7 +117,7 @@ class CameraController { }); state._scannerConfig = ScannerConfiguration( - types, resolution, framerate, detectionMode, position); + types, resolution, framerate, position, detectionMode); state.eventNotifier.value = CameraEvent.resumed; } catch (error, stack) { diff --git a/fast_barcode_scanner/lib/src/overlays/material_overlay.dart b/fast_barcode_scanner/lib/src/overlays/material_overlay.dart index 58d7ae04..c713ab75 100644 --- a/fast_barcode_scanner/lib/src/overlays/material_overlay.dart +++ b/fast_barcode_scanner/lib/src/overlays/material_overlay.dart @@ -5,10 +5,10 @@ import 'material_scanner_painter/material_sensing_painter.dart'; class MaterialPreviewOverlay extends StatefulWidget { const MaterialPreviewOverlay( - {Key? key, this.animateDetection = true, this.aspectRatio = 16 / 9}) + {Key? key, this.showSensing = true, this.aspectRatio = 16 / 9}) : super(key: key); - final bool animateDetection; + final bool showSensing; final double aspectRatio; @override @@ -25,7 +25,7 @@ class MaterialPreviewOverlayState extends State void initState() { super.initState(); - if (widget.animateDetection) { + if (widget.showSensing) { _controller = AnimationController( duration: const Duration(milliseconds: 1100), vsync: this); @@ -40,7 +40,7 @@ class MaterialPreviewOverlayState extends State tween: Tween(begin: 1.0, end: 0.0) .chain(CurveTween(curve: Curves.easeOutCubic)), weight: expand), - // TweenSequenceItem(tween: ConstantTween(0.0), weight: idle), + // TweenSequenceItem(tween: ConstantTween(0.0), weight: wait), ]).animate(_controller); _inflateSequence = TweenSequence([ @@ -49,8 +49,18 @@ class MaterialPreviewOverlayState extends State tween: Tween(begin: 0.0, end: 1.0) .chain(CurveTween(curve: Curves.easeOutCubic)), weight: expand), - // TweenSequenceItem(tween: ConstantTween(0.0), weight: idle), + // TweenSequenceItem(tween: ConstantTween(0.0), weight: wait), ]).animate(_controller); + + _controller.addStatusListener((status) { + if (status == AnimationStatus.completed) { + Future.delayed(const Duration(seconds: 1, milliseconds: 500), () { + _controller.forward(from: _controller.lowerBound); + }); + } + }); + + _controller.forward(); } } @@ -58,7 +68,7 @@ class MaterialPreviewOverlayState extends State Widget build(BuildContext context) { return RepaintBoundary( child: SizedBox.expand( - child: widget.animateDetection + child: widget.showSensing ? _buildAnimation(context) : CustomPaint( painter: MaterialBarcodeFramePainter(widget.aspectRatio))), @@ -71,7 +81,9 @@ class MaterialPreviewOverlayState extends State builder: (context, child) => CustomPaint( painter: MaterialBarcodeFramePainter(widget.aspectRatio), foregroundPainter: MaterialBarcodeSensingPainter( - inflate: _inflateSequence.value, opacity: _opacitySequence.value), + aspectRatio: widget.aspectRatio, + inflate: _inflateSequence.value, + opacity: _opacitySequence.value), ), ); } diff --git a/fast_barcode_scanner/lib/src/overlays/material_scanner_painter/material_sensing_painter.dart b/fast_barcode_scanner/lib/src/overlays/material_scanner_painter/material_sensing_painter.dart index 9d525918..71731f20 100644 --- a/fast_barcode_scanner/lib/src/overlays/material_scanner_painter/material_sensing_painter.dart +++ b/fast_barcode_scanner/lib/src/overlays/material_scanner_painter/material_sensing_painter.dart @@ -1,8 +1,12 @@ import 'package:flutter/material.dart'; class MaterialBarcodeSensingPainter extends CustomPainter { - MaterialBarcodeSensingPainter({required this.inflate, required this.opacity}); + MaterialBarcodeSensingPainter( + {required this.aspectRatio, + required this.inflate, + required this.opacity}); + final double aspectRatio; final double inflate; final double opacity; @@ -12,11 +16,15 @@ class MaterialBarcodeSensingPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final rect = Rect.fromLTWH(0, 0, size.width, size.height); + final screenRect = Rect.fromLTWH(0, 0, size.width, size.height); + final cutOutWidth = screenRect.width - 45; + final cutOutHeight = 1 / aspectRatio * cutOutWidth; final cutOut = RRect.fromRectXY( Rect.fromCenter( - center: rect.center, width: rect.width - 45, height: 165), + center: screenRect.center, + width: cutOutWidth, + height: cutOutHeight), 12, 12); diff --git a/fast_barcode_scanner/pubspec.yaml b/fast_barcode_scanner/pubspec.yaml index a08cbc83..d97a9fff 100644 --- a/fast_barcode_scanner/pubspec.yaml +++ b/fast_barcode_scanner/pubspec.yaml @@ -1,6 +1,6 @@ name: fast_barcode_scanner description: A fast barcode scanner using MLKit on Android and AVFoundation on iOS. -version: 1.1.1 +version: 2.0.0-dev.1 homepage: https://github.com/jhoogstraat/fast_barcode_scanner repository: https://github.com/jhoogstraat/fast_barcode_scanner publish_to: none @@ -12,9 +12,8 @@ environment: dependencies: flutter: sdk: flutter - fast_barcode_scanner_platform_interface: - path: ../fast_barcode_scanner_platform_interface - + fast_barcode_scanner_platform_interface: ^2.0.0-dev.1 + # dependency_overrides: # fast_barcode_scanner_platform_interface: # path: ../fast_barcode_scanner_platform_interface diff --git a/fast_barcode_scanner_platform_interface/pubspec.yaml b/fast_barcode_scanner_platform_interface/pubspec.yaml index e8b113a6..ea1045da 100644 --- a/fast_barcode_scanner_platform_interface/pubspec.yaml +++ b/fast_barcode_scanner_platform_interface/pubspec.yaml @@ -2,7 +2,7 @@ name: fast_barcode_scanner_platform_interface description: A common platform interface for the fast_barcode_scanner plugin. homepage: https://github.com/jhoogstraat/fast_barcode_scanner/tree/master/fast_barcode_scanner_platform_interface repository: https://github.com/jhoogstraat/fast_barcode_scanner -version: 1.0.3 +version: 2.0.0-dev.1 environment: sdk: '>=2.12.0 <3.0.0'