Ray
Ray

Reputation: 4947

Can ZXing.NET read multiple QR barcodes in same image?

I'm in the process of integrating ZXing.NET into a WPF application but I'm using the BarcodeReader.Decode method to read the QR barcode. It works but now I'm wondering what happens when the image have multiple QR barcodes. I want ZXing to read them all into an array. Is this possible? If yes, how? I don't see any method that does this.

Edit: I found out there is a class called QRCodeMultiReader that I can use to read multiple QR barcodes. But the parameter that you send to the decodeMultiple method is of type ZXing.BinaryBitmap. How do I convert a Bitmap into a BinaryBitmap?

Here is what I have, but the results variable is always null when I call decodeMultiple:

public static List<BarCodeDataContract> MultipleDecode(Bitmap image)
{
    var converter = new ImageConverter();
    var bytes = (byte[])converter.ConvertTo(image, typeof(byte[]));
    LuminanceSource source = new RGBLuminanceSource(bytes, image.Width, image.Height);
    var binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));

    var reader = new QRCodeMultiReader();
    var results = reader.decodeMultiple(binaryBitmap);
    var scannedQrBarcodes = new List<BarCodeDataContract>();

    foreach (var result in results)
    {
        if (result == null || result.BarcodeFormat != BarcodeFormat.QR_CODE || !result.Text.Contains(":")) return null;

        var qrCodeData = result.Text.Split(':');
        if (qrCodeData.Length != 2) return null;

        int numericCode;
        if (int.TryParse(qrCodeData[0], out numericCode))
        {
            if (System.Enum.IsDefined(typeof(QrCodeActionPrefixType), (short)numericCode))
            {
                Guid guid;
                if (Guid.TryParse(qrCodeData[1], out guid))
                {
                    scannedQrBarcodes.Add(new BarCodeDataContract()
                    {
                        QrCodeActionPrefixType = (QrCodeActionPrefixType)numericCode,
                        BarCodeObjectUniqueId = guid
                    });
                }
            }
        }
    }
    return scannedQrBarcodes;
}

Upvotes: 1

Views: 5339

Answers (2)

Michael
Michael

Reputation: 2496

The BarcodeReader class implements two interfaces: IBarcodeReader and IMultipleBarcodeReader. The IMultipleBarcodeReader interface supports the method DecodeMultiple. If you set the Property PossibleFormats only to QR_CODE the BarcodeReader uses internally the QRCodeMultiReader implementation if DecodeMultiple is called. If you look for other barcode types it uses the GenericMultipleBarcodeReader.

Btw. if the QR_CODEs are generated with Structured Append support you will find in the ResultMetadata collection the sequence number and parity information for every result which is found. That information helps to build up the final result in the correct order if needed.

Upvotes: 1

Halloween_Udo
Halloween_Udo

Reputation: 69

You can create a new BinaryBitmap by using a Binarizer that processes a LuminanceSource. These are all ZXing related classes.

To get the LuminanceSource you can create a new BitmapLuminanceSource that you pass your Bitmap. (BitmapLuminanceSource' base class is BaseLuminanceSource which base class is LuminanceSource, that is what you want)

The Binarizer turns your LuminanceSource into a BinaryBitmap. This means the resulting image will only have black and white pixels or dots (binary). There are multiple ways to binarize an image and some ways are more suited for other conditions, like a dark background for example. You can try out different Binarizers.

Code:

BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BitmapLuminanceSource(_insert your Bitmap here_)));

Upvotes: 1

Related Questions