Reputation: 1376
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?
Upvotes: 2
Views: 10759
Reputation: 368
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.
Upvotes: -2
Reputation: 368
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.
Upvotes: 4
Reputation: 368
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
Upvotes: 1
Reputation: 323
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.
Upvotes: 1