Android Camera2,我从ImageReader 获取YUV 图像。 U 和 V 缓冲区只有一行(跨步)数据,其余为零
Android Camera2, I aquire YUV image from ImageReader. U and V buffers have only one row(stride) data, the rest is zero
这就是我实例化 ImageReader 的方式。
Size[] sizes = configs.getOutputSizes(ImageFormat.YUV_420_888);
mImageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
Surface rgbCaptureSurface = mImageReader.getSurface();
List<Surface> surfaces = new ArrayList<Surface>();
surfaces.add(rgbCaptureSurface);
//surfaces.add(surface);
mPreviewRequestBuilder
= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//mPreviewRequestBuilder.addTarget(surface);
mPreviewRequestBuilder.addTarget(rgbCaptureSurface);
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);
// Flash is automatically enabled when necessary.
//setAutoFlash(mPreviewRequestBuilder);
// Finally, we start displaying the camera preview.
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
阅读是这样进行的:
public void onImageAvailable(ImageReader reader) {
Image image;
while (true) {
image = reader.acquireLatestImage();
if (image == null) return;
Image.Plane Y = image.getPlanes()[0];
Image.Plane U = image.getPlanes()[1];
Image.Plane V = image.getPlanes()[2];
int Yb = Y.getBuffer().remaining();
int Ub = U.getBuffer().remaining();
int Vb = V.getBuffer().remaining();
byte[] data = new byte[Yb + Ub + Vb];
Y.getBuffer().get(data, 0, Yb);
U.getBuffer().get(data, Yb, Ub);
V.getBuffer().get(data, Yb + Ub, Vb);
我尝试了几种不同的图像格式。我在 LG G3 上测试,API 21 和问题 occurs.On Nexus 4 我没有问题,API 22.
我升级到 API 23,同样的代码工作正常。还在 API 22 上进行了测试,它也有效。
同于:
您的观察是正确的。 API 21 不正确支持 Camera2。这已经被几个人在 SO 上独立发现,例如参见Camera2 API21 not working
所以在API22之前开始使用Camera2是合理的。无法理解为何在此期间没有修改文档。
就我个人而言,我将继续进行 Camera2 研究,但我现在仍然不愿意在我的应用程序中使用 Camera2。我首先想先在很多设备上测试它,在不久的将来,我不希望 "Camera1" 不再被新设备支持。
这就是我实例化 ImageReader 的方式。
Size[] sizes = configs.getOutputSizes(ImageFormat.YUV_420_888);
mImageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
Surface rgbCaptureSurface = mImageReader.getSurface();
List<Surface> surfaces = new ArrayList<Surface>();
surfaces.add(rgbCaptureSurface);
//surfaces.add(surface);
mPreviewRequestBuilder
= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//mPreviewRequestBuilder.addTarget(surface);
mPreviewRequestBuilder.addTarget(rgbCaptureSurface);
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);
// Flash is automatically enabled when necessary.
//setAutoFlash(mPreviewRequestBuilder);
// Finally, we start displaying the camera preview.
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
阅读是这样进行的:
public void onImageAvailable(ImageReader reader) {
Image image;
while (true) {
image = reader.acquireLatestImage();
if (image == null) return;
Image.Plane Y = image.getPlanes()[0];
Image.Plane U = image.getPlanes()[1];
Image.Plane V = image.getPlanes()[2];
int Yb = Y.getBuffer().remaining();
int Ub = U.getBuffer().remaining();
int Vb = V.getBuffer().remaining();
byte[] data = new byte[Yb + Ub + Vb];
Y.getBuffer().get(data, 0, Yb);
U.getBuffer().get(data, Yb, Ub);
V.getBuffer().get(data, Yb + Ub, Vb);
我尝试了几种不同的图像格式。我在 LG G3 上测试,API 21 和问题 occurs.On Nexus 4 我没有问题,API 22.
我升级到 API 23,同样的代码工作正常。还在 API 22 上进行了测试,它也有效。
同于:
您的观察是正确的。 API 21 不正确支持 Camera2。这已经被几个人在 SO 上独立发现,例如参见Camera2 API21 not working
所以在API22之前开始使用Camera2是合理的。无法理解为何在此期间没有修改文档。
就我个人而言,我将继续进行 Camera2 研究,但我现在仍然不愿意在我的应用程序中使用 Camera2。我首先想先在很多设备上测试它,在不久的将来,我不希望 "Camera1" 不再被新设备支持。