Browse Source

allow to scan inverted image

pull/58/head
Khoren Markosyan 2 years ago
parent
commit
11b278e96e
  1. 1
      example/lib/main.dart
  2. 12
      lib/src/logic/camera_stream.dart
  3. 6
      lib/src/ui/reader_widget.dart
  4. 8
      lib/src/utils/image_converter.dart
  5. 23
      lib/src/utils/isolate_utils.dart

1
example/lib/main.dart

@ -55,6 +55,7 @@ class _DemoPageState extends State<DemoPage> {
onScan: (value) { onScan: (value) {
showMessage(context, 'Scanned: ${value.textString ?? ''}'); showMessage(context, 'Scanned: ${value.textString ?? ''}');
}, },
tryInverted: true,
), ),
ListView( ListView(
children: [ children: [

12
lib/src/logic/camera_stream.dart

@ -11,9 +11,15 @@ Future<void> startCameraProcessing() async {
/// Stops reading barcode from the camera /// Stops reading barcode from the camera
void stopCameraProcessing() => isolateUtils?.stopReadingBarcode(); void stopCameraProcessing() => isolateUtils?.stopReadingBarcode();
Future<CodeResult> processCameraImage(CameraImage image, Future<CodeResult> processCameraImage(
{int format = Format.Any, double cropPercent = 0.5}) async { CameraImage image, {
final IsolateData isolateData = IsolateData(image, format, cropPercent); int format = Format.Any,
double cropPercent = 0.5,
bool tryHarder = false,
bool tryInverted = false,
}) async {
final IsolateData isolateData =
IsolateData(image, format, cropPercent, tryHarder, tryInverted);
final CodeResult result = await _inference(isolateData); final CodeResult result = await _inference(isolateData);
return result; return result;
} }

6
lib/src/ui/reader_widget.dart

@ -18,6 +18,8 @@ class ReaderWidget extends StatefulWidget {
required this.onScan, required this.onScan,
this.onControllerCreated, this.onControllerCreated,
this.codeFormat = Format.Any, this.codeFormat = Format.Any,
this.tryHarder = false,
this.tryInverted = false,
this.showCroppingRect = true, this.showCroppingRect = true,
this.scannerOverlay, this.scannerOverlay,
this.showFlashlight = true, this.showFlashlight = true,
@ -33,6 +35,8 @@ class ReaderWidget extends StatefulWidget {
final Function(CodeResult) onScan; final Function(CodeResult) onScan;
final Function(CameraController?)? onControllerCreated; final Function(CameraController?)? onControllerCreated;
final int codeFormat; final int codeFormat;
final bool tryHarder;
final bool tryInverted;
final bool showCroppingRect; final bool showCroppingRect;
final ScannerOverlay? scannerOverlay; final ScannerOverlay? scannerOverlay;
final bool showFlashlight; final bool showFlashlight;
@ -167,6 +171,8 @@ class _ReaderWidgetState extends State<ReaderWidget>
image, image,
format: widget.codeFormat, format: widget.codeFormat,
cropPercent: widget.showCroppingRect ? widget.cropPercent : 0, cropPercent: widget.showCroppingRect ? widget.cropPercent : 0,
tryHarder: widget.tryHarder,
tryInverted: widget.tryInverted,
); );
if (result.isValidBool) { if (result.isValidBool) {
widget.onScan(result); widget.onScan(result);

8
lib/src/utils/image_converter.dart

@ -57,3 +57,11 @@ imglib.Image convertYUV420(CameraImage image) {
return img; return img;
} }
Uint8List invertImage(Uint8List bytes) {
final Uint8List invertedBytes = Uint8List.fromList(bytes);
for (int i = 0; i < invertedBytes.length; i++) {
invertedBytes[i] = 255 - invertedBytes[i];
}
return invertedBytes;
}

23
lib/src/utils/isolate_utils.dart

@ -16,10 +16,14 @@ class IsolateData {
this.cameraImage, this.cameraImage,
this.format, this.format,
this.cropPercent, this.cropPercent,
this.tryHarder,
this.tryInverted,
); );
CameraImage cameraImage; CameraImage cameraImage;
int format; int format;
double cropPercent; double cropPercent;
bool tryHarder;
bool tryInverted;
SendPort? responsePort; SendPort? responsePort;
} }
@ -63,16 +67,33 @@ class IsolateUtils {
final Uint8List bytes = await convertImage(image); final Uint8List bytes = await convertImage(image);
final int cropSize = final int cropSize =
(min(image.width, image.height) * cropPercent).round(); (min(image.width, image.height) * cropPercent).round();
final bool tryHarder = isolateData.tryHarder;
final bool tryInverted = isolateData.tryInverted;
final CodeResult result = readBarcode( CodeResult result = readBarcode(
bytes, bytes,
width: image.width, width: image.width,
height: image.height, height: image.height,
format: isolateData.format, format: isolateData.format,
cropWidth: cropSize, cropWidth: cropSize,
cropHeight: cropSize, cropHeight: cropSize,
tryHarder: tryHarder,
); );
if (result.isValid == 0 && tryInverted) {
// try to invert the image and read again
final Uint8List invertedBytes = invertImage(bytes);
result = readBarcode(
invertedBytes,
width: image.width,
height: image.height,
format: isolateData.format,
cropWidth: cropSize,
cropHeight: cropSize,
tryHarder: tryHarder,
);
}
isolateData.responsePort?.send(result); isolateData.responsePort?.send(result);
} catch (e) { } catch (e) {
isolateData.responsePort?.send(e); isolateData.responsePort?.send(e);

Loading…
Cancel
Save