Navaron Bracke

refactor analyze image in the platform interface

1 import 'dart:async'; 1 import 'dart:async';
  2 +import 'dart:io';
2 3
3 import 'package:flutter/services.dart'; 4 import 'package:flutter/services.dart';
4 import 'package:flutter/widgets.dart'; 5 import 'package:flutter/widgets.dart';
  6 +import 'package:mobile_scanner/src/enums/barcode_format.dart';
5 import 'package:mobile_scanner/src/enums/camera_facing.dart'; 7 import 'package:mobile_scanner/src/enums/camera_facing.dart';
  8 +import 'package:mobile_scanner/src/enums/mobile_scanner_error_code.dart';
6 import 'package:mobile_scanner/src/enums/torch_state.dart'; 9 import 'package:mobile_scanner/src/enums/torch_state.dart';
  10 +import 'package:mobile_scanner/src/mobile_scanner_exception.dart';
7 import 'package:mobile_scanner/src/mobile_scanner_platform_interface.dart'; 11 import 'package:mobile_scanner/src/mobile_scanner_platform_interface.dart';
  12 +import 'package:mobile_scanner/src/objects/barcode.dart';
  13 +import 'package:mobile_scanner/src/objects/barcode_capture.dart';
8 14
9 /// An implementation of [MobileScannerPlatform] that uses method channels. 15 /// An implementation of [MobileScannerPlatform] that uses method channels.
10 class MethodChannelMobileScanner extends MobileScannerPlatform { 16 class MethodChannelMobileScanner extends MobileScannerPlatform {
@@ -31,6 +37,56 @@ class MethodChannelMobileScanner extends MobileScannerPlatform { @@ -31,6 +37,56 @@ class MethodChannelMobileScanner extends MobileScannerPlatform {
31 37
32 int? _textureId; 38 int? _textureId;
33 39
  40 + /// Parse a [BarcodeCapture] from the given [event].
  41 + BarcodeCapture? _parseBarcode(Map<Object?, Object?>? event) {
  42 + if (event == null) {
  43 + return null;
  44 + }
  45 +
  46 + final Object? data = event['data'];
  47 +
  48 + if (data == null || data is! List<Object?>) {
  49 + return null;
  50 + }
  51 +
  52 + final List<Map<Object?, Object?>> barcodes = data.cast<Map<Object?, Object?>>();
  53 +
  54 + if (Platform.isMacOS) {
  55 + return BarcodeCapture(
  56 + raw: event,
  57 + barcodes: barcodes
  58 + .map(
  59 + (barcode) => Barcode(
  60 + rawValue: barcode['payload'] as String?,
  61 + format: BarcodeFormat.fromRawValue(
  62 + barcode['symbology'] as int? ?? -1,
  63 + ),
  64 + ),
  65 + )
  66 + .toList(),
  67 + );
  68 + }
  69 +
  70 + if (Platform.isAndroid || Platform.isIOS) {
  71 + final double? width = event['width'] as double?;
  72 + final double? height = event['height'] as double?;
  73 +
  74 + return BarcodeCapture(
  75 + raw: data,
  76 + barcodes: barcodes.map(Barcode.fromNative).toList(),
  77 + image: event['image'] as Uint8List?,
  78 + size: width == null || height == null ? Size.zero : Size(width, height),
  79 + );
  80 + }
  81 +
  82 + throw const MobileScannerException(
  83 + errorCode: MobileScannerErrorCode.genericError,
  84 + errorDetails: MobileScannerErrorDetails(
  85 + message: 'Only Android, iOS and macOS are supported.',
  86 + ),
  87 + );
  88 + }
  89 +
34 @override 90 @override
35 Stream<TorchState> get torchStateStream { 91 Stream<TorchState> get torchStateStream {
36 return eventsStream 92 return eventsStream
@@ -46,13 +102,13 @@ class MethodChannelMobileScanner extends MobileScannerPlatform { @@ -46,13 +102,13 @@ class MethodChannelMobileScanner extends MobileScannerPlatform {
46 } 102 }
47 103
48 @override 104 @override
49 - Future<bool> analyzeImage(String path) async {  
50 - final bool? result = await methodChannel.invokeMethod<bool>( 105 + Future<BarcodeCapture?> analyzeImage(String path) async {
  106 + final Map<String, Object?>? result = await methodChannel.invokeMapMethod<String, Object?>(
51 'analyzeImage', 107 'analyzeImage',
52 path, 108 path,
53 ); 109 );
54 110
55 - return result ?? false; 111 + return _parseBarcode(result);
56 } 112 }
57 113
58 @override 114 @override
@@ -2,6 +2,7 @@ import 'package:flutter/widgets.dart'; @@ -2,6 +2,7 @@ import 'package:flutter/widgets.dart';
2 import 'package:mobile_scanner/src/enums/camera_facing.dart'; 2 import 'package:mobile_scanner/src/enums/camera_facing.dart';
3 import 'package:mobile_scanner/src/enums/torch_state.dart'; 3 import 'package:mobile_scanner/src/enums/torch_state.dart';
4 import 'package:mobile_scanner/src/method_channel/mobile_scanner_method_channel.dart'; 4 import 'package:mobile_scanner/src/method_channel/mobile_scanner_method_channel.dart';
  5 +import 'package:mobile_scanner/src/objects/barcode_capture.dart';
5 import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 6 import 'package:plugin_platform_interface/plugin_platform_interface.dart';
6 7
7 /// The platform interface for the `mobile_scanner` plugin. 8 /// The platform interface for the `mobile_scanner` plugin.
@@ -28,8 +29,10 @@ abstract class MobileScannerPlatform extends PlatformInterface { @@ -28,8 +29,10 @@ abstract class MobileScannerPlatform extends PlatformInterface {
28 29
29 /// Analyze a local image file for barcodes. 30 /// Analyze a local image file for barcodes.
30 /// 31 ///
31 - /// Returns whether the file at the given [path] contains a barcode.  
32 - Future<bool> analyzeImage(String path) { 32 + /// The [path] is the path to the file on disk.
  33 + ///
  34 + /// Returns the barcodes that were found in the image.
  35 + Future<BarcodeCapture?> analyzeImage(String path) {
33 throw UnimplementedError('analyzeImage() has not been implemented.'); 36 throw UnimplementedError('analyzeImage() has not been implemented.');
34 } 37 }
35 38