在zxing中解码大致流程为:
1:获取摄像头byte[] data
2:对数据进行解析
在zxing客户端源码中
PreviewCallback 摄像头回调 data就是出自这里
PlanarYUVLuminanceSource 继承与LuminanceSource不同的数据原 YUV RGB
RGBLuminanceSource
AutoFocusCallback  自动对焦。不能自动对焦的手机zxing就不能发威了
CameraManager  摄像头管理类。打开,关闭
DecodeThread   线程管理主要利用到了CountDownLatch
DecodeHandler  数据传输中枢。我理解DecodeThread控制线程,DecodeHandler发送数据
DecodeFormatManager  这个配置解码格式。一维码,二维码等
CaptureActivityHandler 这个是解码与avtivity中介。解码成功,失败都用她回调
ViewfinderView  我们看到的扫描框,搞花样就从她入手上面是我对zxing的理解。下面是 二维码从图片解析内容的分析与实现

解决方案 »

  1.   

    public class DecodeImageHandler {
    private static final String TAG = DecodeImageHandler.class.getSimpleName();
    // 解码格式
    private MultiFormatReader multiFormatReader;
    private static final String ISO88591 = "ISO8859_1"; // private Context mContext; public DecodeImageHandler(Context context) {
    // 解码的参数
    Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(2);
    // 能解析的编码类型 和 解析时使用的编码。
    Vector<BarcodeFormat> decodeFormats = new Vector<BarcodeFormat>();
    decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
    decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
    decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
    hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
    hints.put(DecodeHintType.CHARACTER_SET, ISO88591);
    init(context, hints); } public DecodeImageHandler(Context context, Hashtable<DecodeHintType, Object> hints) {
    init(context, hints);
    } private void init(Context context, Hashtable<DecodeHintType, Object> hints) {
    multiFormatReader = new MultiFormatReader();
    multiFormatReader.setHints(hints);
    // mContext = context;
    } public Result decode(Bitmap bitmap) {
    // 首先,要取得该图片的像素数组内容
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    //--------------------------------------------------
    //rgb模式
    int[] data = new int[width * height];
    bitmap.getPixels(data, 0, width, 0, 0, width, height);
    Result rgbResult = rgbModeDecode(data, width, height);
    if (rgbResult != null) {
    data = null;
    return rgbResult;
    } //----------------------------------------------------
    //yuv
    byte[] bitmapPixels = new byte[width * height];
    bitmap.getPixels(data, 0, width, 0, 0, width, height);
    // 将int数组转换为byte数组
    for (int i = 0; i < data.length; i++) {
    bitmapPixels[i] = (byte) data[i];
    }
    // ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    Result yuvResult = yuvModeDecode(bitmapPixels, width, height);
    bitmapPixels = null;
    return yuvResult;
    } // public Result decode(String path) throws IOException {
    // // 解析图片高和宽
    // BitmapFactory.Options options = new BitmapFactory.Options();
    // options.inJustDecodeBounds = true;
    // BitmapFactory.decodeFile(path, options);
    //
    // //从图片直接获取byte[]
    // File file = new File(path);
    // FileInputStream is = new FileInputStream(file);
    // ByteArrayOutputStream os = new ByteArrayOutputStream();
    // int len = -1;
    // byte[] buf = new byte[512];
    // while ((len = is.read(buf)) != -1) {
    // os.write(buf, 0, len);
    // }
    // //关闭流
    // try {
    // is.close();
    // } finally {
    // if (is != null) {
    // is.close();
    // }
    // }
    //
    // //解析
    // return decode(os.toByteArray(), options.outWidth, options.outHeight);
    // } public Result rgbModeDecode(int[] data, int width, int height) {
    Result rawResult = null;
    RGBLuminanceSource source = new RGBLuminanceSource(width, height, data);
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    try {
    rawResult = multiFormatReader.decodeWithState(bitmap);
    } catch (ReaderException re) {
    // continue
    } finally {
    multiFormatReader.reset();
    } //转换乱码
    if (rawResult != null) {
    return converResult(rawResult);
    }
    return rawResult;
    } public Result yuvModeDecode(byte[] data, int width, int height) {
    Result rawResult = null;
    PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height);
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    try {
    rawResult = multiFormatReader.decodeWithState(bitmap);
    } catch (ReaderException re) {
    // continue
    } finally {
    multiFormatReader.reset();
    } //转换乱码
    if (rawResult != null) {
    return converResult(rawResult);
    }
    return rawResult;
    } /**
     * 使用ISO88591进行解码,然后通过ISO88591在进行转换乱码
     */
    private Result converResult(Result rawResult) {
    //复制一个Result,并转码
    String str = rawResult.getText();
    String converText = null;
    try {
    converText = BarcodeUtils.converStr(str, ISO88591);
    } catch (UnsupportedEncodingException e) {
    Logger.getInstance(TAG).debug(e.toString());
    } // FIXME 转化失败--》1:结果置空
    //              --》2:把未解码的内容返回
    if (converText != null) {
    return serResultText(rawResult, converText);
    } else {
    return rawResult;
    }
    } private Result serResultText(Result rawResult, String converText) {
    Result resultResult = new Result(converText, rawResult.getRawBytes(), rawResult.getResultPoints(),
    rawResult.getBarcodeFormat(), System.currentTimeMillis());
    resultResult.putAllMetadata(rawResult.getResultMetadata());
    return resultResult;
    }}
      

  2.   

    从摄像头解码过程:
    获取数据,生成数据源,后台解析我们的思路:
    生成byte[] data 给了他就ok了但是要注意在摄像头取的是yuv数据流,我们把bitmap直接转成byte[]在给后台解析失败率很高。
    上面我是用了两中模式rgbModeDecode  yuvModeDecode
    还是有失败。
    如果把bitmap转成yuv数据?希望高手指点
    在android中解析图片要考虑两个因素1 内存 2数据格式以上就是我的浅谈。有错的地方希望大家之处。
    不知道谁有更好的解析图片二位码的方法
      

  3.   

    bitmap转灰
    public static Bitmap toGrayscale(Bitmap bmpOriginal) {
    int width, height;
    height = bmpOriginal.getHeight();
    width = bmpOriginal.getWidth(); Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
    Canvas c = new Canvas(bmpGrayscale);
    Paint paint = new Paint();
    ColorMatrix cm = new ColorMatrix();
    cm.setSaturation(0);
    ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
    paint.setColorFilter(f);
    c.drawBitmap(bmpOriginal, 0, 0, paint); return bmpGrayscale;
    }
      

  4.   

    这里有个web版的生成器:http://blog.csdn.net/suntongo/article/details/8742023