我正在尝试构建一个相机应用程序,它接受相机预览、处理像素,然后显示新图像。我需要实时进行操作。
根据我在网上阅读的内容和此处的问题,您需要制作自定义表面 View 并通过 onPreviewFrame
方法操作像素数组。我已经构建了一个自定义表面 View 并运行了这个方法。我已将 YUV
转换为 RGB
。
现在,我的问题是,如何在屏幕上实时显示这个新的像素阵列?我是否以某种方式在 onPreviewFrame
方法中返回它?我必须更改 byte[]
数组吗?我是否使用我的新像素阵列并使用位图显示它?有没有办法在不显示预览的情况下从相机预览中获取 byte[]
数组?
如果有人能回答这些问题,并提供代码示例,那就太好了!我是 Android 的新手,所以我需要对答案的解释足以让我理解。这是我运行相机预览的部分代码:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// start preview with new settings
try {
//parameters.setPreviewSize(w, h);
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera)
{
System.out.println("onPreviewFrame");
//transforms NV21 pixel data into RGB pixels
decodeYUV420SP(pixels, data, previewSize.width, previewSize.height);
//Outuput the value of the top left pixel in the preview to LogCat
Log.i("Pixels", "The top right pixel has the following RGB (hexadecimal) values:"
+Integer.toHexString(pixels[0]));
}
});
mCamera.startPreview();
} catch (Exception e){
Log.d(null, "Error starting camera preview: " + e.getMessage());
}
}
这给了我想要显示而不是预览的 rgb 像素阵列。我该怎么做?
最佳答案
您无法操纵连接到相机预览的表面。您在 onPreviewFrame()
中收到的字节数组只是框架在屏幕上显示的内容的副本。此外,您会发现这两个流是异步的:您可以减慢回调速度(例如,通过将一些 sleep()
添加到您的回调中),但预览表面仍然会更新。
您可以通过在其上放置其他 View 来隐藏预览 SurfaceView
,或者您可以使用 setPreviewTexture()
而不是 完全摆脱此 View >setPreviewDisplay()
(注意:在 API 级别 11 中添加)。隐藏表面并不像看起来那么容易:框架可能会将其弹出到顶部,这需要仔细同步相机启动或重新启动布局。
无论如何,隐藏表面后,您可以使用 onPreviewFrame()
中接收的字节数组生成图像并显示它。您可以根据自己的喜好自由操作像素。我认为最佳技术是将像素数据发送到 OpenGL:您可以使用着色器将 YCrCb (NV21) 到 RGB 的转换卸载到 GPU。
关于Android 相机像素操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13548045/