2016-11-18 116 views
6

我正在開發自定義相機API 2應用程序,並且我注意到當我使用ImageReader回調時,某些設備上的捕獲格式轉換不同。如何區分imageReader相機API 2中的NV21和YV12編碼?

例如在Nexus 4中無法正常工作,並且在Nexus5X中看起來沒問題,這裏是輸出。

enter image description here

我初始化的ImageReader這種形式:

mImageReader = ImageReader.newInstance(320, 240, ImageFormat.YUV_420_888,2); 

而且我的回調是簡單的回調的ImageReader回調。

mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() { 

    @Override 
    public void onImageAvailable(ImageReader reader) { 

     try { 
      mBackgroundHandler.post(
       new ImageController(reader.acquireNextImage()) 
      ); 
     } 
     catch(Exception e) 
     { 
      //exception 
     } 
     } 

};

而在Nexus 4的情況下:我有這個錯誤。

D/qdgralloc: gralloc_lock_ycbcr: Invalid format passed: 0x32315659 

當我嘗試在兩個設備中寫入原始文件時,我有這些不同的圖像。所以我明白Nexus 5X圖像具有NV21編碼,而Nexus 4具有YV12編碼。 enter image description here

我找到了image format的規範,我嘗試在ImageReader中獲取格式。 有YV12和NV21選項,但顯然,當我嘗試獲取格式時,我得到了YUV_420_888格式。

int test=mImageReader.getImageFormat(); 

那麼有沒有什麼辦法讓相機輸入格式(NV21或YV12)區分相機類中的這些編碼類型? CameraCharacteristics可能?

在此先感謝。

Unai。 PD:我使用OpenGL在RGB圖像中顯示,我使用Opencv將轉換轉換爲YUV_420_888。

+0

does'Image.getFormat()'返回與'ImageReader'格式相同嗎?看起來你並不孤單:http://stackoverflow.com/questions/34717969/imagereader-format-overridden-in-some-devices – nandsito

+0

@nandsito感謝您的建議,但不幸的是,他們在這兩種情況下返回相同的值35這正是YUV_420_888。 – uelordi

+0

你是否檢查過'Camera.Parameters.getSupportedPictureFormats()'支持哪些格式? – Robert

回答

0

YUV_420_888是一個可以承載NV21和YV12圖像的包裝。如果必須使用飛機和大踏步地進入個別顏色:

ByteBuffer Y = image.getPlanes()[0]; 
ByteBuffer U = image.getPlanes()[1]; 
ByteBuffer V = image.getPlanes()[2]; 

如果下面的像素是NV21格式(如在Nexus 4),該pixelStride將是2,和

int getU(image, col, row) { 
    return getPixel(image.getPlanes()[1], col/2, row/2); 
} 

int getPixel(plane, col, row) { 
    return plane.getBuffer().get(col*plane.getPixelStride() + row*plane.getRowStride()); 
} 

我們採取半列和半行,因爲這是U和V(色度)平面如何存儲在420圖像中。

此代碼僅用於說明,效率非常低,您可能想要使用get(byte[], int, int)或通過片段着色器或通過本機代碼中的JNI函數GetDirectBufferAddress批量訪問像素。你不能使用的是方法plane.array(),因爲平面保證是直接的字節緩衝區。

相關問題