Skip to content

Commit

Permalink
Updates readme and overlay fix
Browse files Browse the repository at this point in the history
  • Loading branch information
jhoogstraat committed Jul 5, 2021
1 parent 51b4851 commit 7647bd3
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 44 deletions.
4 changes: 3 additions & 1 deletion fast_barcode_scanner/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
41 changes: 23 additions & 18 deletions fast_barcode_scanner/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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';
Expand Down Expand Up @@ -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
4 changes: 2 additions & 2 deletions fast_barcode_scanner/example/lib/scanner_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ class _ScannerScreenState extends State<ScannerScreen> {
position: CameraPosition.back,
onScan: (code) => codeStream.add(code),
children: const [
MaterialPreviewOverlay(animateDetection: false),
BlurPreviewOverlay()
MaterialPreviewOverlay(showSensing: true),
// BlurPreviewOverlay()
],
),
bottomSheet: SafeArea(
Expand Down
2 changes: 1 addition & 1 deletion fast_barcode_scanner/lib/src/barcode_camera.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class BarcodeCameraState extends State<BarcodeCamera> {

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));
}

Expand Down
14 changes: 7 additions & 7 deletions fast_barcode_scanner/lib/src/camera_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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<BarcodeType>? types,
Resolution? resolution,
Expand All @@ -48,8 +48,8 @@ class ScannerConfiguration {
types ?? this.types,
resolution ?? this.resolution,
framerate ?? this.framerate,
detectionMode ?? this.detectionMode,
position ?? this.position,
detectionMode ?? this.detectionMode,
);
}
}
Expand Down Expand Up @@ -100,8 +100,8 @@ class CameraController {
List<BarcodeType> types,
Resolution resolution,
Framerate framerate,
DetectionMode detectionMode,
CameraPosition position,
DetectionMode detectionMode,
void Function(Barcode)? onScan) async {
state.eventNotifier.value = CameraEvent.init;

Expand All @@ -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) {
Expand Down
26 changes: 19 additions & 7 deletions fast_barcode_scanner/lib/src/overlays/material_overlay.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,7 +25,7 @@ class MaterialPreviewOverlayState extends State<MaterialPreviewOverlay>
void initState() {
super.initState();

if (widget.animateDetection) {
if (widget.showSensing) {
_controller = AnimationController(
duration: const Duration(milliseconds: 1100), vsync: this);

Expand All @@ -40,7 +40,7 @@ class MaterialPreviewOverlayState extends State<MaterialPreviewOverlay>
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([
Expand All @@ -49,16 +49,26 @@ class MaterialPreviewOverlayState extends State<MaterialPreviewOverlay>
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();
}
}

@override
Widget build(BuildContext context) {
return RepaintBoundary(
child: SizedBox.expand(
child: widget.animateDetection
child: widget.showSensing
? _buildAnimation(context)
: CustomPaint(
painter: MaterialBarcodeFramePainter(widget.aspectRatio))),
Expand All @@ -71,7 +81,9 @@ class MaterialPreviewOverlayState extends State<MaterialPreviewOverlay>
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),
),
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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);

Expand Down
7 changes: 3 additions & 4 deletions fast_barcode_scanner/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion fast_barcode_scanner_platform_interface/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down

0 comments on commit 7647bd3

Please sign in to comment.