This project has moved. For the latest updates, please go here.

Fastest way of decoding barcode in C#?

Dec 23, 2013 at 3:49 AM
I am currently using luminancesource method to make the decoding process faster.
LuminanceSource ls = new ZXing.RGBLuminanceSource(ToByteArray(image), image.Width, image.Height);
var result = reader.Decode(ls);
I saw various method for the luminancesource such as using a binarizer etc. but what do they mean, what do they do and does it make the decoding process faster?

Also, what is the fastest way to decode barcodes using C#? Is there a method to specify the region of the image to scan and decode barcodes?
Coordinator
Dec 29, 2013 at 8:35 PM
Using the luminance source this way doesn't make the decoding faster. Mainly it depends on the code which is inside the method "ToByteArray".
The "Decode" method can be called with a byte array, too. Internally it does exactly the same thing like your code here.

If you want to make the decoding process faster you can do different things:
  • restrict the list of possible codes which should be looked for (var reader = new BarcodeReader { Options = new DecodingOptions { PossibleFormats = new List<BarcodeFormat> { BarcodeFormat.QR_CODE }}})
  • restrict the area of the image which is scanned for barcodes. You can do this by cropping the source image. Or you use a custom luminance source.
  • if you have very large images with a high resolution then you should shrink it. Up to 1000 pixel for height or width is enough for most use cases.
  • don't use TryHarder=true or AutoRotate=true
  • use the GlobalHistogramBinarizer instead of the default HybridBinarizer (can be changed with a delegate function which has to be given by the constructor of the BarcodeReader class)
Dec 30, 2013 at 2:03 AM
Thanks for your reply.

"ToByteArray" code:
        private static byte[] ToByteArray(Image img)
        {
            byte[] byteArray = new byte[0];
            using (MemoryStream stream = new MemoryStream())
            {
                img.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
                stream.Close();

                byteArray = stream.ToArray();
            }
            return byteArray;
        }
Will the above method or using the BitmapLuminanceSource (below) be faster?
LuminanceSource ls = new ZXing.BitmapLuminanceSource(image);
Is the GlobalHistogramBinarizer for QR_CODE barcode formats? I'm using the barcode reader to decode CODE_39 barcode formats.
Coordinator
Jan 6, 2014 at 10:26 PM
Edited Jan 6, 2014 at 10:27 PM
The main problem with the "ToByteArray": it doesn't work as expected.
The call to
img.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
does not only give the raw rgb values. It generates also the whole format header stuff for bmp.
You have to cut away the first bunch of bytes before using it with the barcode reader.

On the other hand, in my small test the following snippet
LuminanceSource ls = new ZXing.BitmapLuminanceSource(image);
is faster than
LuminanceSource ls = new ZXing.RGBLuminanceSource(ToByteArray(image), image.Width, image.Height);
My suggestion is, use the image directly with the barcode reader
var result = reader.Decode(image);
The class GlobalHistogramBinarizer is for all types of code. It only uses a different way to calculate the binary values from the luminance values.