2

I am trying to scan a local image through ZBar, but as ZBar don't give any documentation for Android but only give detailed documentation for iPhone I had customized camera test activity too much. But I didn't get any success.

In ZBar cameratest activity

PreviewCallback previewCb = new PreviewCallback() {
    public void onPreviewFrame(byte[] data, Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        Size size = parameters.getPreviewSize();

        Image barcode = new Image(size.width, size.height, "Y800");
        barcode.setData(data);

        int result = scanner.scanImage(barcode);

        if (result != 0) {
            previewing = false;
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();

            SymbolSet syms = scanner.getResults();
            for (Symbol sym : syms) {
                scanText.setText("barcode result " + sym.getData());
                barcodeScanned = true;
            }
        }
    }
};

I want to customize this code so that it uses a local image from the gallery and gives me the result. How do I customize this code for giving a local image from the gallery and scan that image?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ShujatAli
  • 1,376
  • 2
  • 14
  • 26
  • For Android use http://code.google.com/p/zxing - tutorial here: http://tekeye.biz/2012/scan-barcode-from-android-app – Daniel S. Fowler Jul 25 '13 at 14:08
  • Zxing is external app . if the Zxing app is not installed in users mobile , the user has to download Zxing app from playstore . where As Zbar is included as library in my project just what i need. – ShujatAli Jul 26 '13 at 05:34

4 Answers4

4

Try this out:

Bitmap barcodeBmp = BitmapFactory.decodeResource(getResources(),
                                                 R.drawable.barcode);
int width = barcodeBmp.getWidth();
int height = barcodeBmp.getHeight();
int pixels = new int;
barcodeBmp.getPixels(pixels, 0, width, 0, 0, width, height);
Image barcode = new Image(width, height, "RGB4");
barcode.setData(pixels);
int result = scanner.scanImage(barcode.convert("Y800"));

Or using the API, refer to HOWTO: Scan images using the API.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
brianha289
  • 338
  • 1
  • 8
  • i had tried this long before. but it gives "Syntax error on token "int", Dimensions expected after this token" at this line. – ShujatAli Jan 07 '14 at 06:15
  • i had found the same answer as yours at sourceforge android developers forum . http://sourceforge.net/p/zbar/discussion/2308158/thread/ce0d36f8 – ShujatAli Jan 07 '14 at 06:17
  • 4
    for future reader `pixels` should be initialized as `int[] pixels = new int[width * height];` – zionpi Aug 12 '15 at 03:42
1

Java port of Zbar's scanner accepts only Y800 and GRAY pixels format (https://github.com/ZBar/ZBar/blob/master/java/net/sourceforge/zbar/ImageScanner.java) which is ok for raw bytes captured from the camera preview. But images from the Androis's Gallery are JPEG comressed usually and their pixels are not in Y800, so you can make scanner work by converting image's pixels to Y800 format. See this official support forum's thread for sample code. To calculate pixels array length just use imageWidth*imageHeight formula.

@shujatAli your example image palette's format is grayscale, convertation it to RGB made your code snippet to work for me. You can change pallete's format using some image manipulation program. I used GIMP.

Pavel
  • 323
  • 4
  • 11
1

I don't know clearly for Android, but on iOS do as:

//Action when user tap on button to call ZBarReaderController

- (IBAction)brownQRImageFromAlbum:(id)sender {
    ZBarReaderController *reader = [ZBarReaderController new];
    reader.readerDelegate = self;
    reader.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; // Set ZbarReaderController point to the local album
    ZBarImageScanner *scanner = reader.scanner;
    [scanner setSymbology: ZBAR_QRCODE
                   config: ZBAR_CFG_ENABLE
                       to: 1];
    [self presentModalViewController: reader animated: YES];

}


- (void) imagePickerController: (UIImagePickerController *) picker
                  didFinishPickingMediaWithInfo: (NSDictionary *) info {

    UIImage *imageCurrent = (UIImage*)[info objectForKey:UIImagePickerControllerOriginalImage];
    self.imageViewQR.image = imageCurrent;
    imageCurrent = nil;

    // ADD: get the decode results
    id<NSFastEnumeration> results =
    [info objectForKey: ZBarReaderControllerResults];
    ZBarSymbol *symbol = nil;
    for (symbol in results)
        break;

    NSLog(@"Content: %@", symbol.data);

    [picker dismissModalViewControllerAnimated: NO];
}

Reference for more details: http://zbar.sourceforge.net/iphone/sdkdoc/optimizing.html

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
brianha289
  • 338
  • 1
  • 8
  • 1
    zbar has very very detailed documentation . and i had no problems in ios . but no documentation for android zbar sdk. so i want help in android zbar sdk – ShujatAli Dec 24 '13 at 06:29
-2

Idea from HOWTO: Scan images using the API:

#include <iostream>
#include <Magick++.h>
#include <zbar.h>

using namespace std;
using namespace zbar;

int main (int argc, char **argv)
{
    if(argc < 2)
        return(1);

    // Create a reader
    ImageScanner scanner;

    // Configure the reader
    scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);

    // Obtain image data
    Magick::Image magick(argv[1]);  // Read an image file
    int width = magick.columns();   // Extract dimensions
    int height = magick.rows();
    Magick::Blob blob;              // Extract the raw data
    magick.modifyImage();
    magick.write(&blob, "GRAY", 8);
    const void *raw = blob.data();

    // Wrap image data
    Image image(width, height, "Y800", raw, width * height);

    // Scan the image for barcodes
    int n = scanner.scan(image);

    // Extract results
    for (Image::SymbolIterator symbol = image.symbol_begin();
        symbol != image.symbol_end();
        ++symbol) {

        // Do something useful with results
        cout << "decoded " << symbol->get_type_name()
             << " symbol \"" << symbol->get_data() << '"' << endl;
    }

    // Clean up
    image.set_data(NULL, 0);

    return(0);
}

Follow the above code and change it so it is relevant in your language programming.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
brianha289
  • 338
  • 1
  • 8