Search code examples
androidbarcodezxing

How to decode a barcode from camera preview using zxing library in android?


I want to implement standalone scanner in my android application.I'm using zxing's core.jar library in my project.

I need to decode a barcode from camera preview.But i don't know how to implement it.Because there is no official documentation.

Can you provide me a simple example on followings things? 1.Initialize the camera and getting preview. 2.Decode the barcode from preview.

or

Is there any example project to do this?


Solution

  • Take a look at my simple implementation: https://github.com/piobab/code-scanner

    I use ZBar library but if you want you can change ZBarScannerView.java implementation to ZXingScannerView (the rest of the code is ok):

    public class ZXingScannerView extends ScannerView {
    public interface ResultHandler {
        public void handleResult(Result result);
    }
    
    private MultiFormatReader mMultiFormatReader;
    private ResultHandler mResultHandler;
    
    public ZXingScannerView(Context context) {
        super(context);
        setupScanner(null);
    }
    
    public ZXingScannerView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        setupScanner(null);
    }
    
    /**
     * Specify recognized codes types.
     * @param codeTypes list of codes types from ZXing library
     */
    public void setCodeTypes(List<com.google.zxing.BarcodeFormat> codeTypes) {
        setupScanner(codeTypes);
    }
    
    private void setupScanner(List<com.google.zxing.BarcodeFormat> symbols) {
        Map<DecodeHintType,Object> hints = new EnumMap<DecodeHintType,Object>(DecodeHintType.class);
        // Add specific formats
        hints.put(DecodeHintType.POSSIBLE_FORMATS, symbols);
        mMultiFormatReader = new MultiFormatReader();
        mMultiFormatReader.setHints(hints);
    }
    
    /**
     * Register callback in order to receive data from scanner.
     * @param resultHandler
     */
    public void setResultHandler(ResultHandler resultHandler) {
        mResultHandler = resultHandler;
    }
    
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        Camera.Size size = parameters.getPreviewSize();
        int width = size.width;
        int height = size.height;
    
        Result rawResult = null;
        PlanarYUVLuminanceSource source = buildLuminanceSource(data, width, height);
    
        if(source != null) {
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            try {
                rawResult = mMultiFormatReader.decodeWithState(bitmap);
            } catch (ReaderException re) {
    
            } catch (NullPointerException npe) {
    
            } catch (ArrayIndexOutOfBoundsException aoe) {
    
            } finally {
                mMultiFormatReader.reset();
            }
        }
    
        if (rawResult != null) {
            stopCamera();
            if(mResultHandler != null) {
                mResultHandler.handleResult(rawResult);
            }
        } else {
            camera.setOneShotPreviewCallback(this);
        }
    }
    
    public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
        Rect rect = getFramingRectInPreview(width, height);
        if (rect == null) {
            return null;
        }
        // Go ahead and assume it's YUV rather than die.
        PlanarYUVLuminanceSource source = null;
    
        try {
            source = new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
                    rect.width(), rect.height(), false);
        } catch(Exception e) {
        }
    
        return source;
    }
    

    }

    If you use gradle add 'com.google.zxing:core:2.2' to your dependencies.