API 21のCamera2のCamera.PreviewCallbackに相当するものはありますか、SurfaceTextureにマッピングしてビットマップをプルするよりも優れていますか?カメラからプレビューデータをYUVとしてプルできるようにする必要がありますか?
GoogleのCamera2Basicサンプルコードから開始できます。
ImageReader
の表面をターゲットとしてプレビューキャプチャリクエストに追加する必要があります。
//set up a CaptureRequest.Builder with the output Surface
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
その後、ImageReader.OnImageAvailableListener
:
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
if (image != null) {
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
Bitmap bitmap = fromByteBuffer(buffer);
image.close();
}
} catch (Exception e) {
Log.w(LOG_TAG, e.getMessage());
}
}
};
Bitmap
からByteBuffer
を取得するには:
Bitmap fromByteBuffer(ByteBuffer buffer) {
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes, 0, bytes.length);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
はい、 ImageReader クラスを使用します。
ImageFormat.YUV_420_888形式と希望のサイズを使用してImageReaderを作成します(使用しているカメラデバイスでサポートされているサイズを選択していることを確認してください)。
次に、SurfaceのImageReader.getSurface()を使用して、CameraDevice.createCaptureSession()に提供します。
最後に、繰り返しキャプチャリクエストで、ImageReader提供のサーフェスをターゲットとして追加してから、キャプチャセッションで繰り返しリクエストとして設定します。