2016-10-13 83 views
2

Camera2 APIを使用してImageReader(YUV_420_888フォーマット)でカメラのプレビューを設定しようとしています。Android Camera2プレビューの出力サイズ

[4032x3024,4000x3000,3840x2160,3288x2480,3200x2400,2592x1944,2688x1512,2048x1536,1920x1080,1600x1200,1440x1080,1280x960,1280x768,1280x720,1024x768,800x600,864x480,800x480,720x480,640x480,640x360,352x288,320x240,176x144,160x120] 

するImageReaderのインスタンスを準備し、キャプチャ要求を繰り返すとCaptureSessionを起動します:

mImageReader = ImageReader.newInstance(W,H, ImageFormat.YUV_420_888,1); 

StreamConfigurationMap scmap = camCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 
Size previewSizes[] = scmap.getOutputSizes(ImageReader.class); 

私のネクサス5Xは、次のサイズをサポートしています。まず第一に、私は、サポートされているプレビューサイズを選択する必要があります

次に、OnImageAvailableListenerの各プレビューフレーム(さらに処理し、GLESを介して表示するため)を読み込もうとしています。そして、私が知りたい - どのように多くの私が受け取ったYチャネルバイト:

public void onImageAvailable(ImageReader reader) { 
     ByteBuffer yBuffer = mImageReader.acquireNextImage().getPlanes()[0].getBuffer(); 
     Log.d("Camera2Debug","Y-channel bytes received: " + yBuffer.remaining()); 
     ... 
    } 

YUV_420_888画像のためのYチャネルはW幅x高バイト、含まれている必要があります - 幅、Hを - 考慮する画像の高さです。

問題:いくつかの場合 プレビューがyBufferの実際のサイズが期待値幅x高)と一致していないサイズをサポート。例えば

:それはデバイスでサポートされている場合でも、私はneccessaryプレビューサイズを使用することはできません。この問題に

Preview Size | Y-bytes received | Y-bytes expected | match 
4032x3024  | 12 192 768  | 12 192 768  | yes 
1920x1080  | 2 073 600  | 2 073 600  | yes 
1440x1080  | 1 589 728  | 1 555 200  | no 
1280x960  | 1 228 800  | 1 228 800  | yes 
1280x768  | 983 040  | 983 040  | yes 
800x600  | 499 168  | 480 000  | no 
... 
499168 

に起因。

私は間違っていますか?

+0

返されたイメージの幅と高さを記録することでさらにデバッグすることができますが、最初にサイズを取得するときに 'scmap.getOutputSizes(ImageFormat.YUV_420_888) 'を使用したいと考えています。ドキュメントによって、 'getOutputSizes(Class )'は 'PRIVATE'フォーマットのサイズを返します。こちらをご覧ください:https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMap.html#getOutputSizes(java.lang.Class ) – msandiford

+0

ご意見ありがとうございます。 'acquireNextImage()'によって返されたImageのサイズが正しいこと(プレビューサイズに等しい)について言及することを忘れました。問題は 'getPlanes()[0] .getBuffer()'のサイズにあります。 – frumle

+0

解決済み:[リンク](http://stackoverflow.com/questions/30405977/nexus-9-camera2-api-yuv-420-888-vs-getoutputsizes)。 – frumle

答えて

2

https://developer.android.com/reference/android/media/Image.Plane.html#getRowStride()を考慮していない可能性があります。これは幅よりも大きいかもしれませんが(少なくともそれに等しい)最後の行が最後の画素過去の任意のパディングが含まれていないため、 - 実際のバッファサイズは(幅rowStride)の減算と

size = rowStride * height - (rowStride - width) 

あろう。

+0

あなたは正しいです、データが配列内にどのように格納されているか気にしませんでした(古いカメラAPIからPreviewCallbackを使用したように)。だから今私は手からアレイから "有用な"データを抽出する必要がありますか? – frumle

+1

はい、データを使用する必要がある場合。カメラのハードウェアは一般にストライドを使用する。なぜなら、各行のサイズは、メモリマッピング要件のために、しばしば16ピクセル/バイトの倍数である必要があるからである。 古いAPIにはストライドがありませんでした。このため、デバイスの勇気を取り除くための余分なコピーが発生することがよくありました。これは余分なオーバーヘッドで、これで回避できるようになりました。これ以上の作業は必要ありません。 –

関連する問題