Marcelo Dias
Marcelo Dias

Reputation: 429

How to crop a large image to scan for barcode

I'm developing a WP8 app to scan barcode using ZXing. It can scan the barcode if the image only contains the ITF barcode. However, it is not working if the barcode is inside a large image.

So I guess that I have to crop the large image into smaller ones to apply the process of scanning. Am I correct?

So, my question is: Is there some best practice to do that, or I need to apply some algorithm to pick portions of the large image randomly?

Bellow is my code:

        StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");

        BitmapImage bitmapImage = await GetBitmapImage(folder, "LargeImage.png");

        WriteableBitmap btmMap = new WriteableBitmap(bitmapImage);
        var rgb = new BitmapLuminanceSource(btmMap);

        var hybrid = new HybridBinarizer(rgb);
        BinaryBitmap binBitmap = new BinaryBitmap(hybrid);

        Dictionary<DecodeHintType, object> zxingHints
            = new Dictionary<DecodeHintType, object>() { { DecodeHintType.TRY_HARDER, true } };

        Reader reader = new ZXing.OneD.MultiFormatOneDReader(zxingHints);

        try
        {
            Result result = reader.decode(binBitmap);
            if (result != null)
            {
                this.resultText = result.Text;
            }
        }
        catch (Exception ex)
        {
            this.resultText = ex.Message;
        }

Upvotes: 2

Views: 2964

Answers (2)

HackSlash
HackSlash

Reputation: 5813

ZXing has a built-in method to crop your image before decoding. It happens at the LuminanceSource step, which is where the color image becomes gray-scale based on Luminance of each pixel. It is done this way to decrease the amount of data that needs to be processed.

EXAMPLE:

var rgb = new BitmapLuminanceSource(New BitmapLuminanceSource(btmMap)
    .Crop(_frame.Left, _frame.Top, _frame.Width, _frame.Height));

Where _frame is a rectangle describing the area you want to search for the barcode. This rectangle is usually described by drawing a viewport in your UI for the user to center the barcode in.

This answer is mostly for other people who end up here from a Google search because there are many reasons why your code isn't working and you have likely moved on from this project by now. For example: why are you loading the image from a PNG file instead of the webcam built in to the phone?

Upvotes: 4

Matt
Matt

Reputation: 4610

I would suggest using the Lumia Imaging SDK (former Nokia Imaging SDK) to give you hardware accelerated filters, like the CropFilter example taken from this page: https://msdn.microsoft.com/en-us/library/lumia.imaging.transforms.cropfilter.aspx

using (var filterEffect = new FilterEffect(source))
{
    // Initialize the filter and add the filter to the FilterEffect collection
    var filter = new CropFilter(new Windows.Foundation.Rect( 260, 210, 670, 446));

    filterEffect.Filters = new IFilter[] { filter };

    // Create a target where the filtered image will be rendered to
    var target = new WriteableBitmap(width, height);

    // Create a new renderer which outputs WriteableBitmaps
    using (var renderer = new WriteableBitmapRenderer(filterEffect, target))
    {
        // Render the image with the filter(s)
        await renderer.RenderAsync();

        // Set the output image to Image control as a source
        ImageControl.Source = target;
    }

    await SaveEffectAsync(filterEffect, "CropFilter.jpg", outputImageSize);
}

Upvotes: 2

Related Questions