ZBar Android扫描本地QR或条形码图像

时间:2013-07-25 06:49:34

标签: android zbar-sdk zbar

我正在尝试通过ZBar扫描本地图片,但由于ZBar没有为Android提供任何文档但仅提供detailed documentation for iPhone我过多地定制了相机测试活动。但我没有取得任何成功。

在ZBar cameratest活动中

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;
            }
        }
    }
};

我想自定义此代码,以便它使用图库中的本地图像并为我提供结果。如何自定义此代码以从库中提供本地图像并扫描该图像?

5 个答案:

答案 0 :(得分:4)

试试这个:

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"));

或使用API​​,请参阅 HOWTO: Scan images using the API

答案 1 :(得分:1)

Zbar扫描仪的Java端口仅接受Y800和GRAY像素格式(https://github.com/ZBar/ZBar/blob/master/java/net/sourceforge/zbar/ImageScanner.java),这对于从相机预览中捕获的原始字节是可以的。但是来自Androis画廊的图像通常是JPEG压缩的,它们的像素不在Y800中,因此您可以通过将图像的像素转换为Y800格式来使扫描仪工作。有关示例代码,请参阅this官方支持论坛的主题。要计算像素数组长度,只需使用imageWidth * imageHeight公式。

@shujatAli您的示例图像调色板的格式是灰度,将其转换为RGB使您的代码片段适合我。您可以使用某些图像处理程序更改托盘的格式。我用过GIMP。

答案 2 :(得分:1)

我不清楚知道Android,但在iOS上执行:

//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];
}

参考更多详情:http://zbar.sourceforge.net/iphone/sdkdoc/optimizing.html

答案 3 :(得分:0)

扩展Accepted Answer

private ImageScanner mScanner = new ImageScanner();


/**
 * using zbar scan the bitmap
 */
private void scanQRImageZbar(Bitmap barcodeBmp) {
    int width = barcodeBmp.getWidth();
    int height = barcodeBmp.getHeight();

    int[] pixels = new int[width * height];
    barcodeBmp.getPixels(pixels, 0, width, 0, 0, width, height);
    Image barcode = new Image(width, height, "RGB4");
    barcode.setData(pixels);
    int result = mScanner.scanImage(barcode.convert("Y800"));

    if (result != 0) {
        // save result in @var symSet
        SymbolSet symSet = mScanner.getResults();
        final Result rawResult = new Result();

        for (Symbol sym : symSet) {
            // symData will have the resultant code value
            String symData;
            if (Build.VERSION.SDK_INT >= 19) {
                symData = new String(sym.getDataBytes(), StandardCharsets.UTF_8);
            } else {
                symData = sym.getData();
            }

            // save it in rawResult
            if (!TextUtils.isEmpty(symData)) {
                rawResult.setContents(symData);
                rawResult.setBarcodeFormat(BarcodeFormat.getFormatById(sym.getType()));
                break;
            }
        }

        // toast message of content
        new AlertDialog.Builder(FullScannerActivity.this).setMessage(rawResult.getContents()).show();
        Log.e("onPreviewFrame: ", rawResult.getContents());
    }
}

答案 4 :(得分:-2)

来自 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);
}

按照上面的代码进行更改,使其与您的语言编程相关。