2016-09-09 61 views
0

我試圖創建一個程序,它直接從Camera2預覽處理圖像,並且在實際處理傳入圖像時,我一直遇到問題。BitmapFactory.getByteArray只適用於字節數組來自存儲器

在我OnImageAvailableListener.onImageAvailable()回調,我發現了一個ImageReader對象,從中我acquireNextImage()和傳遞Image對象到我的助手功能。從那裏,我將它轉換成一個字節數組,並嘗試進行處理。相反,每次我到達將其轉換爲Bitmap的部分時,BitmapFactory.getByteArray都會返回null,即使字節數組的格式是正確格式的JPEG。

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener 
     = new ImageReader.OnImageAvailableListener() { 
    @Override 
    public void onImageAvailable(ImageReader imageReader) { 
     Image image = imageReader.acquireNextImage(); 
     ProcessBarcode(image); 
     image.close(); 
    } 
}; 

private void ProcessBarcode(Image image) { 
    ByteBuffer buffer = image.getPlanes()[0].getBuffer(); 
    int bufferSize = buffer.remaining(); 
    byte[] bytes = new byte[bufferSize]; 
    buffer.get(bytes); 

    FileOutputStream output = null; 
    try { 
     output = new FileOutputStream(mFile); 
     output.write(bytes); 
     output.close(); 
    } catch (IOException e) { 
     // Do something clever 
    } 

    // This call FAILS 
    //Bitmap b = BitmapFactory.decodeByteArray(bytes, 0, buffer.remaining(), o); 

    // But this call WORKS? 
    Bitmap b = BitmapFactory.decodeFile(mFile.getAbsolutePath()); 

    detector = new BarcodeDetector.Builder(getActivity()) 
      .setBarcodeFormats(Barcode.EAN_13 | Barcode.ISBN) 
      .build(); 

    if (b != null) { 
     Frame isbnFrame = new Frame.Builder().setBitmap(b).build(); 
     SparseArray<Barcode> barcodes = detector.detect(isbnFrame); 

     if (barcodes.size() != 0) { 
      Log.d("Barcode decoded: ",barcodes.valueAt(0).displayValue); 
     } 
     else { 
      Log.d(TAG, "No barcode detected"); 
     } 
    } 
    else { 
     Log.d(TAG, "No bitmap detected"); 
    } 
} 

ImageReader設置如下:

mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, 2); 
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler); 

基本上我看到的是,如果我直接使用字節數組,而不先保存到內部存儲器,相機預覽速度快,瞬間,儘管Bitmap總是爲空,所以我實際上沒有執行任何處理。如果我將字節數組保存到內存中,那麼我可能會得到2-3fps,但處理按我的意圖工作。

回答

0

在致電buffer.get(bytes)之後,buffer.remaining()將返回0,因爲您只是通讀整個ByteBuffer。 remaining()將告訴您在當前位置和緩衝區限制之間剩下多少個字節,並且調用get()將位置向前移動讀取的字節數。

因此,當你做decodeByteArray(bytes,0, buffer.remaining(), 0),你實際上不解碼任何字節。

如果您嘗試decodeByteArray(bytes, 0, bytes.length, 0),它工作嗎?

+0

謝謝艾迪!直接獲取'bytes.length'而不是'buffer.remaining()'解決了這個問題。我仍然有可怕的掃描速度,但我認爲這是解碼條形碼的問題,而不是與捕獲圖像有關的任何事情。 – Jared

+0

如果你想要高幀率,不要捕捉JPEG - 通常這些速度很慢(一般爲1-3fps,最好爲10fps)。改爲使用ImageFormat.YUV_420_888,至少在預覽分辨率下保證以30fps運行。您也應該避免爲每個圖像創建一個新的條形碼掃描器;我假設你可以重複使用多次。 –

+0

我發現了另一個涉及這個主題的線程(雖然不是我明顯的錯誤),並且它也提出了YUV_420_888格式,所以我很快就會切換到這個。我確實在預覽模式下修正了幀速率,通過過濾掉相機尚未獲取AF和AE鎖定時拍攝的幀。所以現在我正在顯示所有的預覽幀,但是隻有在我對攝像機進行了正面鎖定之後才進行條形碼掃描。現在已經接近實時。 – Jared