2015-10-20 105 views
1

我们正在开发Android应用程序并使用ZXing扫描QR码。有没有办法使用ZXing获得全帧解码QR码?在Android上使用ZXing全屏访问

以下方法被添加到PlanarYUVLuminanceSource类。

public void saveFrame() { 
    try { 
     YuvImage image = new YuvImage(yuvData, ImageFormat.NV21, getWidth(), getHeight(), null); 
     File file = new File(Environment.getExternalStorageDirectory().getPath() + "/frame.jpeg"); 
     FileOutputStream fos = new FileOutputStream(file); 
     image.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 100, fos); 
    } catch (FileNotFoundException e) { 
     Log.e(TAG, "FileNotFoundException!"); 
    } 
} 

如下DecodeHandler类中调用,

private void decode(byte[] data, int width, int height) { 
     long start = System.currentTimeMillis(); 
     Result rawResult = null; 
     PlanarYUVLuminanceSource source = CameraManager.get() 
       .buildLuminanceSource(data, width, height); 
     BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); 
     try { 
      rawResult = multiFormatReader.decodeWithState(bitmap); 
     } catch (ReaderException re) { 
      // continue 
     } finally { 
      multiFormatReader.reset(); 
     } 

     if (rawResult != null) { 
      // Don't log the barcode contents for security. 
      long end = System.currentTimeMillis(); 
      Log.d(TAG, "Found barcode in " + (end - start) + " ms"); 
      Message message = Message.obtain(activity.getHandler(), 
        R.id.zxinglib_decode_succeeded, rawResult); 
      Bundle bundle = new Bundle(); 
      bundle.putParcelable(DecodeThread.BARCODE_BITMAP, 
        source.renderCroppedGreyscaleBitmap()); 
      source.saveFrame(); 
      message.setData(bundle); 
      message.sendToTarget(); 
     } else { 
      Message message = Message.obtain(activity.getHandler(), 
        R.id.zxinglib_decode_failed); 
      message.sendToTarget(); 
     } 
    } 

下面是结果图像,

Here is result image

回答

0

最后我发现了一个解决方案。它基于PlanarYUVLuminanceSource类的renderCroppedGreyscaleBitmap()方法。以下是我如何更改decode()方法。

private void decode(byte[] data, int width, int height) { 
    long start = System.currentTimeMillis(); 
    Result rawResult = null; 
    PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(data, width, height); 
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); 
    try { 
     rawResult = multiFormatReader.decodeWithState(bitmap); 
    } catch (ReaderException re) { 
     // continue 
    } finally { 
     multiFormatReader.reset(); 
    } 

    if (rawResult != null) { 
     // Don't log the barcode contents for security. 
     long end = System.currentTimeMillis(); 
     Log.d(TAG, "Found barcode in " + (end - start) + " ms"); 
     // Grab & save frame 
     Bitmap wholeBmp = renderGrayScaleBitmap(data, width, height); 
     if(wholeBmp != null) 
      saveBitmap(wholeBmp, "frame.png"); 
     else 
      Log.e(TAG, "Bitmap of frame is empty!"); 
     Message message = Message.obtain(activity.getHandler(), R.id.zxinglib_decode_succeeded, rawResult); 
     Bundle bundle = new Bundle(); 
     bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap()); 
     message.setData(bundle); 
     message.sendToTarget(); 
    } else { 
     Message message = Message.obtain(activity.getHandler(), R.id.zxinglib_decode_failed); 
     message.sendToTarget(); 
    } 
} 

从解码数据创建位图

private Bitmap renderGrayScaleBitmap(byte[] data, int width, int height) { 
    int[] pixels = new int[width * height]; 
    int inputOffset = width; 
    for (int y = 0; y < height; y++) { 
     int outputOffset = y * width; 
     for (int x = 0; x < width; x++) { 
      int grey = data[inputOffset + x] & 0xff; 
      pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101); 
     } 
     inputOffset += width; 
    } 
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    bitmap.setPixels(pixels, 0, width, 0, 0, width, height); 
    return bitmap; 
} 

保存位图到SD卡

private void saveBitmap(Bitmap bmp, String name) { 
    FileOutputStream out = null; 
    try { 
     String filename = Environment.getExternalStorageDirectory().toString() + "/" + name; 
     Log.i(TAG, "writtenPath=" + filename); 
     out = new FileOutputStream(filename); 
     bmp.compress(Bitmap.CompressFormat.PNG, 100, out); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      if (out != null) { 
       out.close(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

喜,茅,如果调用renderGrayScaleBitmap(),灰度图像将被保存,这是你的通缉的结果?我想使用yuv数据的一部分,而不需要从颜色变为灰度数据,然后将这些数据发送给zxing来处理。换句话说,我只是想使用原始数据。你知道怎么做了感谢 – mmm2006

+0

我的代码:?YuvImage yuvImage =新YuvImage(source.getMatrix(), \t \t \t \t \t ImageFormat.NV21,source.getWidth(),source.getHeight(), \t \t \t \t \t null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); \t \t \t yuvImage.compressToJpeg( \t \t \t \t \t新的矩形(0,0,source.getWidth(), – mmm2006

+0

所有结果就像你第一次保存的图像。许多绿色带。我不知道原因。你能帮我解释一下吗?谢谢。 – mmm2006