juliansteenbakker / mobile_scanner

A universal scanner for Flutter based on MLKit. Uses CameraX on Android and AVFoundation on iOS.
BSD 3-Clause "New" or "Revised" License
820 stars 477 forks source link

need help on ImagePicker integration #146

Open MkLHX opened 2 years ago

MkLHX commented 2 years ago

Hello, i open an issue because my first post in on the PR #40

I try to troubleshoot the imagePicker use with mobile_scanner.

Here the sample code:

imagePickerLogic(context) async {
    final ImagePicker _picker = ImagePicker();
    String qrCodeContent = "";
    // Pick an image
    final XFile image = await _picker.pickImage(
      source: ImageSource.gallery,
    );
    if (image != null) {
      if (await cameraController.analyzeImage(image.path)) {
        if (!mounted) return;
        MobileScanner(
          allowDuplicates: true,
          controller: cameraController,
          onDetect: (barcode, args) {
            qrCodeContent = barcode.rawValue;
            DeviceIp device = DeviceIp.fromJson(jsonDecode(qrCodeContent));
            storeNewDevice(device);
            displayConfirm(device);
          });
      } else {
        if (!mounted) return;
        ScaffoldMessenger.of(context).showSnackBar(
           SnackBar(
            content: Text(Providers(context).T("qr_code_not_found")),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

The problem seems to be on the onDetect event after the controller.analyzeImage() return true.

apoleo88 commented 2 years ago

Original code:

  Future<bool> analyzeImage(String path) async {
    return methodChannel.invokeMethod('analyzeImage', path) as bool;
  }

Error: type 'Future<dynamic>' is not a subtype of type 'bool' in type cast

To: return (await methodChannel.invokeMethod('analyzeImage', path)) as bool;

I created a pull request

apoleo88 commented 2 years ago

To analyze an image from the gallery I do something similar:

  final picker = ImagePicker();
  final XFile? result = await picker.pickImage(source: ImageSource.gallery);
  if(result == null) return;

  MobileScannerController cameraController = MobileScannerController();
  late StreamSubscription sub;
  sub = cameraController.barcodesController.stream.listen((barcode) {
    if (barcode.rawValue == null) {
      debugPrint('Failed to scan Barcode');
    } else {
      ElaborateCode(barcode.rawValue);
      print("sent one code to be elaborated");
    }
    sub.cancel();
  });

  await cameraController.analyzeImage(result.path);
MkLHX commented 2 years ago

Hi @apoleo88 thank you this is a good way to manage it.

MkLHX commented 1 year ago

Hi there, Since mobile_scanner upgraded to v3, I'm facing an issue with the deprecated method barcodesController

I didn't find any equivalent for barcodesControllerin the MobileScannerController class.

When I try to use .barcodes.listen

Nothing happens during stream read.

here is my actual deprecated code:

  imagePickerLogic(context) async {
    final ImagePicker _picker = ImagePicker();
    String qrCodeContent = "";
    // Pick an image
    final XFile image = await _picker.pickImage(
      source: ImageSource.gallery,
    );
    if (image != null) {

      StreamSubscription sub;
      sub = cameraController.barcodesController.stream.listen((barcode) async {
        if (barcode.rawValue == null) {
          debugPrint('Failed to scan Barcode');
        } else {
          qrCodeContent = barcode.rawValue;
          DeviceIp device = DeviceIp.fromJson(jsonDecode(qrCodeContent));
          var config = await Providers(context).appInfos.storage.getLocalConfig(null);
          bool new_device = false;
          for(var d in config.devices){
            if(d.name == device.name){
              new_device = true;
            }
          }
          if(new_device == false){
            storeNewDevice(device);
            displayConfirm(device);
          }
          else{
            displayDeviceExist(device);
          }  
        }
        sub.cancel();
      });
      await cameraController.analyzeImage(image.path);
    }
  }

What I've tried:

  imagePickerLogic(context) async {
    final ImagePicker _picker = ImagePicker();
    String qrCodeContent = "";
    // Pick an image
    final XFile? image = await _picker.pickImage(
      source: ImageSource.gallery,
    );
    if (image != null) {
      late StreamSubscription sub;
      // sub = cameraController.barcodesController.stream.listen((barcode) async {
      sub = await cameraController.barcodes.listen((barcode) async {
        print(barcode);
        if (barcode.raw == null) {
          debugPrint('Failed to scan Barcode');
        } else {
          qrCodeContent = barcode.raw!;
          print(qrCodeContent);
        }
        //     DeviceIp device = DeviceIp.fromJson(jsonDecode(qrCodeContent));
        //     var config = await Providers(context).appInfos.storage.getLocalConfig(null);
        //     bool new_device = false;
        //     for(var d in config.devices){
        //       if(d.name == device.name){
        //         new_device = true;
        //       }
        //     }
        //     if(new_device == false){
        //       storeNewDevice(device);
        //       displayConfirm(device);
        //     }
        //     else{
        //       displayDeviceExist(device);
        //     }
        //   }
        sub.cancel();
      });
      await cameraController.analyzeImage(image.path);
    }
  }

There is nothing about imagePicker in examples and documentation to use the barCode content and work with it.

If somebody can help me on this topic it will be very helpful.

MkLHX commented 1 year ago

@apoleo88 maybe you can help me