Skip to content

Commit

Permalink
fix(performances): improve scan performances
Browse files Browse the repository at this point in the history
  • Loading branch information
gwaelesadeo authored and MayuriXx committed Oct 26, 2021
1 parent ea5557b commit 60a4b7c
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 90 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 2.2.1

- Improve scan performance (JS Library changed)
- Improve scan performance

## 2.2.0

Expand Down
2 changes: 1 addition & 1 deletion example/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

<!-- Initialize Firebase -->
<script src="/__/firebase/init.js"></script>
<script src="https://unpkg.com/@zxing/browser@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2/dist/quagga.min.js"></script>
<script src="js/barcode.js"></script>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
Expand Down
32 changes: 21 additions & 11 deletions example/web/js/barcode.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
function detectBarcode(dataUrl, callback) {
const hints = new Map();
hints.set('TRY_HARDER', true);
const codeReader = new ZXingBrowser.BrowserMultiFormatReader(hints);
console.log('ZXing code reader initialized');
codeReader.decodeFromImageUrl(dataUrl).then((result) => {
console.log(result);
callback(result.text);
}).catch((err) => {
//console.error(err);
})
console.log(`Started decode for image from ${dataUrl.src}`);
Quagga.decodeSingle({
decoder: {
readers: [
"code_128_reader",
"ean_reader",
"ean_8_reader",
"code_39_reader",
"code_39_vin_reader",
"code_93_reader"
] // List of active readers
},
locate: true, // try to locate the barcode in the image
src: dataUrl // or 'data:image/jpg;base64,' + data
}, function (result) {
if (result && result.codeResult) {
console.log("result", result.codeResult.code);
callback(result.codeResult.code);
} else {
console.log("not detected");
}
});
}
93 changes: 51 additions & 42 deletions lib/cam_code_scanner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ class CamCodeScanner extends StatefulWidget {
/// controller to control the camera from outside
final CamCodeScannerController? controller;

/// The color of the background mask
final Color backgroundColor;

/// shows the current analysing picture
final bool showScannerLine;

/// Camera barcode scanner widget
/// Params:
/// * showDebugFrames [true|false] - shows the current analysing picture
Expand All @@ -38,8 +44,10 @@ class CamCodeScanner extends StatefulWidget {
required this.onBarcodeResult,
required this.width,
required this.height,
this.refreshDelayMillis = 400,
this.refreshDelayMillis = 1000,
this.controller,
this.backgroundColor = Colors.black54,
this.showScannerLine = true,
});

@override
Expand All @@ -54,7 +62,7 @@ class _CamCodeScannerState extends State<CamCodeScanner> {
late Widget _webcamWidget;

/// Debug frame Image widget to insert into the tree
//late Widget _imageWidget;
late Widget _imageWidget;

/// The barcode result
String barcode = '';
Expand Down Expand Up @@ -94,9 +102,9 @@ class _CamCodeScannerState extends State<CamCodeScanner> {
viewType: 'webcamVideoElement$time',
);

//_imageWidget = HtmlElementView(
// viewType: 'imageElement',
//);
_imageWidget = HtmlElementView(
viewType: 'imageElement',
);

// Set the initialized flag
setState(() {
Expand Down Expand Up @@ -142,43 +150,44 @@ class _CamCodeScannerState extends State<CamCodeScanner> {
height: widget.height,
child: _webcamWidget,
),
// if (widget.showDebugFrames)
// Container(
// width: widget.width,
// height: widget.height,
// color: Colors.black.withOpacity(0.8),
// child: Text(''),
// ),
// Positioned(
// top: (widget.height / 2) - (widget.height * .1),
// left: (widget.width * .1),
// child: Container(
// decoration: BoxDecoration(
// border: Border.all(
// color: Colors.green,
// width: 1,
// ),
// ),
// child: SizedBox(
// width: widget.width * .8,
// height: widget.height * .2,
// child: widget.showDebugFrames
// ? _imageWidget
// : Container(),
// ),
// ),
// ),
//Center(
// child: CustomPaint(
// size: Size(
// widget.width * .5,
// widget.height * .2,
// ),
// painter: _ScannerLine(
// color: Colors.red,
// ),
// ),
//),
Container(
width: widget.width,
height: (widget.height / 2) - (widget.height / 8),
color: widget.backgroundColor,
child: Text(''),
),
Positioned(
top: (widget.height / 2) + (widget.height / 8),
left: 0,
child: Container(
width: widget.width,
height: (widget.height / 2) - (widget.height / 8),
color: widget.backgroundColor,
child: Text(''),
),
),
if (widget.showDebugFrames)
Positioned(
top: widget.height * .4,
left: 0,
child: SizedBox(
width: widget.width,
height: widget.height * .2,
child: _imageWidget,
),
),
if (widget.showScannerLine)
Center(
child: CustomPaint(
size: Size(
widget.width,
widget.height * .2,
),
painter: ScannerLine(
color: Colors.red,
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
Expand Down
95 changes: 60 additions & 35 deletions lib/camcode_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:camcode/barcode_results.dart';
import 'package:camcode/dart_ui_stub/dart_ui.dart' as ui;

import 'package:camcode/barcode.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';

Expand Down Expand Up @@ -42,6 +43,10 @@ class CamcodeWeb {
/// Completer to get enumerateDevices result
late Completer<List<String>> _enumerateDevicesCompleter;

int frameSize = 1;
int counter = 0;
int maxAttempt = 4;

/// Registering method
static void registerWith(Registrar registrar) {
final channel = MethodChannel(
Expand Down Expand Up @@ -98,15 +103,19 @@ class CamcodeWeb {
/// - initialize video
/// - start video streaming
/// - start picture snapshot timer scheduling
int initialize(double width, double height, int refreshDelayMillis) {
int initialize(
double width,
double height,
int refreshDelayMillis,
) {
completer = Completer<String>();
_enumerateDevicesCompleter = Completer<List<String>>();
_barcodeResults.clear();

// Create a video element which will be provided with stream source
_webcamVideoElement = VideoElement()
..width = width.toInt()
..height = height.toInt()
..width = 1920
..height = 1080
..style.width = '100%'
..style.height = '100%'
..style.objectFit = 'contain'
Expand All @@ -115,14 +124,14 @@ class CamcodeWeb {
_webcamVideoElement.setAttribute('playsinline', 'true');

imageElement = ImageElement()
..width = width.toInt()
..height = (height * .2).toInt()
..width = 1920
..height = 1080
..style.width = '100%'
..style.height = (height * .2).toInt().toString() + 'px';
..style.height = '100%';

_canvasElement = CanvasElement(
width: width.toInt(),
height: height.toInt(),
width: 1920,
height: 1080,
);

final time = DateTime.now().microsecondsSinceEpoch;
Expand Down Expand Up @@ -174,8 +183,6 @@ class CamcodeWeb {
'deviceId':
_selectedDeviceId != null ? {'exact': _selectedDeviceId} : null,
'facingMode': {'exact': 'environment'},
//'width': width.toInt(),
//'height': height.toInt()
}
};
} else {
Expand All @@ -184,8 +191,6 @@ class CamcodeWeb {
'video': {
'deviceId':
_selectedDeviceId != null ? {'exact': _selectedDeviceId} : null,
//'width': width.toInt(),
//'height': height.toInt()
}
};
}
Expand Down Expand Up @@ -215,6 +220,7 @@ class CamcodeWeb {

/// Scan loop
Future<void> _scan(int refreshDelayMillis) async {
counter = 0;
_timer = Timer.periodic(
Duration(
milliseconds: refreshDelayMillis,
Expand All @@ -229,33 +235,52 @@ class CamcodeWeb {
/// and process it for barcode identification
Future<void> _takePicture() async {
final context = _canvasElement.context2D;
context.filter = 'grayscale(1)';

//context.drawImageScaledFromSource(
// _webcamVideoElement,
// _webcamVideoElement.videoWidth * .1, // X IN VIDEO
// (_webcamVideoElement.videoHeight * .5) -
// (_webcamVideoElement.videoHeight * .1), // Y IN VIDEO
// _webcamVideoElement.videoWidth * .8, // WIDTH IN VIDEO
// _webcamVideoElement.videoHeight * .2, // HEIGHT IN VIDEO
// 0, // X IN CANVAS
// 0, // Y IN CANVAS
// (_canvasElement.width ?? 0), // WIDTH IN CANVAS
// _canvasElement.height ?? 0, // HEIGHT IN CANVAS
//);

context.drawImageScaled(
_webcamVideoElement,
0,
0,
_webcamVideoElement.width,
_webcamVideoElement.height,
);
// context.filter = 'grayscale(1)';

switch (frameSize) {
case 1:
context.drawImageScaledFromSource(
_webcamVideoElement,
_webcamVideoElement.videoWidth * .2,
_webcamVideoElement.videoHeight * .4,
_webcamVideoElement.videoWidth * .6,
_webcamVideoElement.videoHeight * .2,
0,
0,
_webcamVideoElement.width,
_webcamVideoElement.height,
);
break;
default:
context.drawImageScaledFromSource(
_webcamVideoElement,
0,
_webcamVideoElement.videoHeight * .4,
_webcamVideoElement.videoWidth,
_webcamVideoElement.videoHeight * .2,
0,
0,
_webcamVideoElement.width,
_webcamVideoElement.height,
);
break;
}

debugPrint(
'Webcam taille : ${_webcamVideoElement.height} & ${_webcamVideoElement.width}');
debugPrint(
'Webcam video taille : ${_webcamVideoElement.videoHeight} & ${_webcamVideoElement.videoWidth}');

final dataUrl = _canvasElement.toDataUrl('image/jpeg', 1.0);
imageElement.src = dataUrl;

detectBarcode(dataUrl, allowInterop((result) => onBarcodeResult(result)));

counter++;

if (counter >= maxAttempt) {
counter = 0;
frameSize = frameSize == 0 ? 1 : 0;
}
}

/// Method called on barcode result to finish the process and send result
Expand Down

0 comments on commit 60a4b7c

Please sign in to comment.