khoren93 / flutter_zxing

Flutter plugin for scanning and generating QR codes using the ZXing library, supporting Android, iOS, and desktop platforms
https://pub.dev/packages/flutter_zxing
MIT License
89 stars 50 forks source link

readBarcode does not work #91

Open TahaMsv opened 1 year ago

TahaMsv commented 1 year ago

Hi. I need to read about 40 barcodes from a single image at once. I have attempted to split the image into 30 smaller and equal parts and read the barcodes from each part individually. But when I use 'readBarcode', It doesn't work and I'm getting nothing. This is my code:

List splitImageParts = []; @override void initState() { // TODO: implement initState WidgetsBinding.instance.addPostFrameCallback((_) async { List imageBytes = await getImageBytes('assets/images/bs_image2.png'); imglib.Image? inputImage = imglib.decodeImage(Uint8List.fromList(imageBytes)); splitImageParts = await splitImage(inputImage: inputImage!, horizontalPieceCount: 4, verticalPieceCount: 10); }); super.initState(); }

Future<List> getImageBytes(String imagePath) async { ByteData imageData = await rootBundle.load(imagePath); Uint8List bytes = imageData.buffer.asUint8List(); return bytes.toList(); }

Future<List> splitImage({required imglib.Image inputImage, required int horizontalPieceCount, required int verticalPieceCount}) async {

imglib.Image image = inputImage;
int x = 0, y = 0;
int width = (image.width / horizontalPieceCount).round();
int height = (image.height / verticalPieceCount).round();

// split image to parts
List<imglib.Image> parts = <imglib.Image>[];
for (int i = 0; i < verticalPieceCount; i++) {
  for (int j = 0; j < horizontalPieceCount; j++) {
    parts.add(imglib.copyCrop(image, x: x, y: y, width: width, height: height));
    x += width;
  }
  x = 0;
  y += height;
}

// convert image from image package to Image Widget to display
List<Image> outputImageList = <Image>[];
for (var img in parts) {
  // ByteData imageData = await rootBundle.load(image);
  Uint8List bytes = img.buffer.asUint8List();
  Code? barcode = zx.readBarcode(bytes, width: width, height: height);
  if (barcode != null) {
    if (barcode.text != null) {
      print(barcode.text);
    }
  }
  outputImageList.add(Image.memory(imglib.encodeJpg(img)));
}
return outputImageList;

}

khoren93 commented 1 year ago

Thanks for letting me know about your barcode reading issue.

One possible solution is to use the readBarcodesImagePath method instead of the readBarcode method. This method reads multiple barcodes from an image file.

You can use this method to read all the barcodes from a single image at once. Here's an example code snippet that you can use:

// To read multiple barcodes from XFile
XFile xFile = XFile('Your image path');
DecodeParams params = DecodeParams(maxSize: 1920); // also try to set larger image max size. Default is 768
Codes result = await zx.readBarcodesImagePath(xFile, params: params);

Let me know if this helps or if you have any other questions.

TahaMsv commented 1 year ago

Thank you for your response. Your suggestion was very helpful. I tried your solution, but it only found about 4 or 5 out of 40 barcodes. I decided to combine it with my own solution by splitting the original image into 40 parts and passing them to the method you suggested. This helped me read more barcodes, and sometimes I was able to read all of them. However, in some cases, I still missed 3 barcodes. Do you know why this is happening? How can I improve my method to ensure that I can always read all of the barcodes?

khoren93 commented 1 year ago

I'm glad to hear that my suggestion was helpful to you. Regarding the issue of missing barcodes, it's hard to tell the exact reason without seeing the images you are working with. It could be due to various factors such as image quality, barcode size, or barcode density in the image.

To help you better, could you please provide a sample image or two that you are working with? This will allow me to test your method and provide you with more targeted suggestions on how you can improve your approach.

TahaMsv commented 1 year ago

Yes, sure. In the image below, three barcodes (35, 36, and 37) are not read: bs_image8

while in the second image, all of the barcodes can be read:

bs_image12

TahaMsv commented 1 year ago

I also worked with the image below, but I couldn't read any barcodes. I think this may be because they are in "Code 128" format. Do you have any suggestions on what I can do to add support for this format?

bs_image15