2015-10-20 56 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