Browse Source

added processCameraImage function

pull/3/head
Khoren Markosyan 3 years ago
parent
commit
6a4f75925c
  1. 35
      lib/flutter_zxing.dart
  2. 10
      lib/isolate_utils.dart
  3. 42
      lib/reader_widget.dart

35
lib/flutter_zxing.dart

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';
import 'package:camera/camera.dart';
@ -10,6 +11,7 @@ import 'package:flutter/services.dart';
import 'package:image/image.dart' as imglib;
import 'generated_bindings.dart';
import 'isolate_utils.dart';
export 'generated_bindings.dart';
export 'reader_widget.dart';
@ -17,6 +19,7 @@ export 'writer_widget.dart';
export 'image_converter.dart';
export 'scanner_overlay.dart';
/// The main class for reading barcodes from images or camera.
class FlutterZxing {
static const MethodChannel _channel = MethodChannel('flutter_zxing');
@ -27,6 +30,8 @@ class FlutterZxing {
static final bindings = GeneratedBindings(dylib);
static IsolateUtils? isolateUtils;
static bool logEnabled = false;
static void setLogEnabled(bool enabled) {
@ -36,6 +41,16 @@ class FlutterZxing {
/// Returns a version of the zxing library
static String version() => bindings.version().cast<Utf8>().toDartString();
/// Starts reading barcode from the camera
static Future startCameraProcessing() async {
// Spawn a new isolate
isolateUtils = IsolateUtils();
await isolateUtils?.startReadingBarcode();
}
/// Stops reading barcode from the camera
static stopCameraProcessing() => isolateUtils?.stopReadingBarcode();
/// Reads barcode from String image path
static Future<CodeResult?> readImagePathString(
String path, {
@ -114,7 +129,25 @@ class FlutterZxing {
return result;
}
static int get _logEnabled => logEnabled ? 1 : 0;
static Future<CodeResult> processCameraImage(
CameraImage image, int format, double cropPercent) async {
var isolateData = IsolateData(image, format, cropPercent);
CodeResult result = await _inference(isolateData);
return result;
}
/// Runs inference in another isolate
static Future<CodeResult> _inference(IsolateData isolateData) async {
ReceivePort responsePort = ReceivePort();
isolateUtils?.sendPort
?.send(isolateData..responsePort = responsePort.sendPort);
var results = await responsePort.first;
return results;
}
static int get _logEnabled {
return logEnabled ? 1 : 0;
}
static String formatName(int format) => _formatNames[format] ?? 'Unknown';
}

10
lib/isolate_utils.dart

@ -33,9 +33,9 @@ class IsolateUtils {
SendPort? get sendPort => _sendPort;
Future<void> start() async {
Future<void> startReadingBarcode() async {
_isolate = await Isolate.spawn<SendPort>(
entryPoint,
readBarcodeEntryPoint,
_receivePort.sendPort,
debugName: kDebugName,
);
@ -43,13 +43,13 @@ class IsolateUtils {
_sendPort = await _receivePort.first;
}
void stop() {
void stopReadingBarcode() {
_isolate?.kill(priority: Isolate.immediate);
_isolate = null;
_sendPort = null;
}
static void entryPoint(SendPort sendPort) async {
static void readBarcodeEntryPoint(SendPort sendPort) async {
final port = ReceivePort();
sendPort.send(port.sendPort);
@ -66,7 +66,7 @@ class IsolateUtils {
image.width, image.height, cropSize, cropSize);
isolateData.responsePort?.send(result);
} on Exception catch (e) {
} catch (e) {
isolateData.responsePort?.send(e);
}
}

42
lib/reader_widget.dart

@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'package:camera/camera.dart';
@ -60,8 +59,7 @@ class _ReaderWidgetState extends State<ReaderWidget>
void initStateAsync() async {
// Spawn a new isolate
isolateUtils = IsolateUtils();
await isolateUtils?.start();
await FlutterZxing.startCameraProcessing();
availableCameras().then((cameras) {
setState(() {
@ -94,8 +92,8 @@ class _ReaderWidgetState extends State<ReaderWidget>
@override
void dispose() {
FlutterZxing.stopCameraProcessing();
controller?.dispose();
isolateUtils?.stop();
super.dispose();
}
@ -116,7 +114,7 @@ class _ReaderWidgetState extends State<ReaderWidget>
await controller?.initialize();
controller?.startImageStream(processCameraImage);
} on CameraException catch (e) {
_showCameraException(e);
debugPrint('${e.code}: ${e.description}');
}
controller?.addListener(() {
@ -131,30 +129,15 @@ class _ReaderWidgetState extends State<ReaderWidget>
widget.onControllerCreated?.call(controller);
}
void _showCameraException(CameraException e) {
logError(e.code, e.description);
showInSnackBar('Error: ${e.code}\n${e.description}');
}
void showInSnackBar(String message) {}
void logError(String code, String? message) {
if (message != null) {
debugPrint('Error: $code\nError Message: $message');
} else {
debugPrint('Error: $code');
}
}
processCameraImage(CameraImage image) async {
if (!_isProcessing) {
_isProcessing = true;
try {
var isolateData =
IsolateData(image, widget.codeFormat, widget.cropPercent);
/// perform inference in separate isolate
CodeResult result = await inference(isolateData);
CodeResult result = await FlutterZxing.processCameraImage(
image,
widget.codeFormat,
widget.cropPercent,
);
if (result.isValidBool) {
if (widget.beep) {
FlutterBeep.beep();
@ -175,15 +158,6 @@ class _ReaderWidgetState extends State<ReaderWidget>
return null;
}
/// Runs inference in another isolate
Future<CodeResult> inference(IsolateData isolateData) async {
ReceivePort responsePort = ReceivePort();
isolateUtils?.sendPort
?.send(isolateData..responsePort = responsePort.sendPort);
var results = await responsePort.first;
return results;
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;

Loading…
Cancel
Save