我在慢慢关注Nexus 6时遇到了这个问题。 我开发相机应用程序,现在我使用camera2 API。
对于应用程序需求,我们创建具有2个表面的预览请求 - SurfaceView(取景器) - YUV ImageReader表面(使用hstogram计算中的数据)
还有一个关键点!如果只添加取景器表面,则会正常进行对焦。但随着镜头移动的视觉步骤,这些表面聚焦发生得很慢!
代码非常标准,根据谷歌文档撰写:
mImageReaderPreviewYUV = ImageReader.newInstance(previewWidth, previewHeight, ImageFormat.YUV_420_888, 2);
previewRequestBuilder = camDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewRequestBuilder.addTarget(getCameraSurface()); //Add surface of SurfaceView
previewRequestBuilder.addTarget(mImageReaderPreviewYUV); //Add ImageReader
mCaptureSession.setRepeatingRequest(previewRequestBuilder.build(), captureCallback null);
答案 0 :(得分:3)
系统logcat是否显示有关缓冲区不可用的任何警告? 预览帧速率是慢还是平滑(~30fps)但是聚焦只是奇怪的工作?
如果是前者,您可能无法以30 fps的速度将Image对象返回到ImageReader(通过使用它们关闭它们),因此相机设备缺乏填充缓冲区,并且无法保持30fps预览。
要测试这个,请实现最小的ImageReaderListener.onImageAvailable(ImageReader reader)方法,该方法只是立即返回图像:
public class TestImageListener extends ImageReaderListener {
public void onImageAvailable(ImageReader reader) {
Image img = reader.acquireNextImage();
img.close();
}
}
...
mImageReaderPreviewYUV.setOnImageAvailableListener(new TestImageListener());
如果这样可以让您获得流畅的预览,那么您的图像处理速度太慢。 作为一种解决方案,您应该增加ImageReader中缓冲区的数量,并使用reader.acquireLatestImage()来删除旧缓冲区,并且每次计算直方图时只处理最新的图像。
答案 1 :(得分:0)
我在N6上遇到了同样的问题,我觉得它现在更顺畅了 - 在相机表面之前添加ImageReader表面:
previewRequestBuilder = camDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewRequestBuilder.addTarget(mImageReaderPreviewYUV); //Add ImageReader
previewRequestBuilder.addTarget(getCameraSurface()); //Add surface of SurfaceView
我还用N4 / 5.0.1测试了我的相机应用程序,并且两种方式都可以在那里完美运行。