android5.0使用camera2 api实现实时渲染,在显示预览部分出现的问题

lzq08ms 2015-05-27 09:02:31
因为要做实时渲染功能的相机,因此第一步自然是获取预览图然后保证能实时处理
试过opencv的相机处理方式,通过给相机设置一个不显示的surface,然后将获取的yuv图像数据刷到自己的surfaceview上
这个例子在5.0下可以正常运行,然而在5.0上没有办法给相机设置一个空的surface,程序抛异常

所以转而改用camera2来解决问题
现在的方案是通过修改ImageReader的接受图像类型,在回调中处理图片数据,然后将图像刷到自己的surfaceview上
所有代码写完后,获取到得图像是绿色的一层,不知道为什么,相关代码如下,希望高手指教

或者有什么好的做实时渲染功能的方案也可以请教一下

//设置ImageReader监听接收的图像类型
largest = Collections.max(Arrays.asList(map
.getOutputSizes(ImageFormat.YUV_420_888)),
new CompareSizesByArea());

bitmap = Bitmap.createBitmap(largest.getWidth(),
largest.getHeight(), Config.ARGB_8888);
mImageReader = ImageReader.newInstance(largest.getWidth(),
largest.getHeight(), ImageFormat.YUV_420_888, /* maxImages */
2);
mImageReader.setOnImageAvailableListener(
mOnImageAvailableListener, mBackgroundHandler);


分别获取yuv图像的三个通道函数,将yuv420格式转换为argb8888格式颜色数据
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {

@Override
public void onImageAvailable(ImageReader reader) {
synchronized (mThread) {
Log.d(tag, "previewing");
Image img = reader.acquireLatestImage();
if (img == null)
return;
ByteBuffer[] buffer = new ByteBuffer[3];
for (int i = 0; i < 3; i++) {
buffer[i] = img.getPlanes()[i].getBuffer();
}
rgb = new int[img.getWidth() * img.getHeight()];

byte[] y_bytes = new byte[buffer[0].remaining()];
byte[] cb_bytes = new byte[buffer[1].remaining()];
byte[] cr_bytes = new byte[buffer[2].remaining()];

buffer[0].get(y_bytes, 0, buffer[0].remaining());
buffer[1].get(cb_bytes, 0, buffer[1].remaining());
buffer[2].get(cr_bytes, 0, buffer[2].remaining());

decodeYUV420SPargb8888(rgb, y_bytes, cb_bytes, cr_bytes,
largest.getWidth(), largest.getHeight());

img.close();

// 保存文件
try {
FileOutputStream fos = new FileOutputStream(
Environment.getExternalStorageDirectory()
+ "/test/yuv");
fos.write(y_bytes);
fos.write(cb_bytes);
fos.write(cr_bytes);
fos.close();
Log.d(tag, "save");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mThread.notify();
}

}

};


我通过将yuv获取到的三通道字节数据直接写入文件,用yuv查看文件查看后也是带有一层绿色的预览图像,基本可以判断转换函数没有问题
...全文
4419 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
lbknxy 2017-01-20
  • 打赏
  • 举报
回复
楼主问题解决了吗? 现在也在学camera2 我是将预览在通过opengl或vulkan在gpu解码为rgb, 一开始我以为YUV420_888是,Y、U、V三个分量在palne里独立存储的, 并以为结构是这样的: plane[0] :YYYYYYYYYYYY。。。。 size = w x h plane[1] :UUUU。。。。 size = w x h / 4 plane[2 ] :VVVV。。。 size = w x h / 4 把结果打印出来却是: plane[0] :YYYYYYYYYYYYY。。。 size = w x h plane[1] :UVUVUVUVUVU。。。 size = w x h / 2 plane[2] :VUVUVUVUVUV。。。 size = w x h / 2 并且plane[1] 和 plane[2] 错位相等。 也就是 plane2[ i + 1 ] == plane1[ i ] 。 所以如果将plane[0] 和plane[1] 接在一起就可以构成 NV12预览格式。将plane[0]和plane[2] 结合到一起就可以得到Camera1 API的NV21预览格式。 这两种方法我都尝试了,显示 没发现有什么问题。 Camera2的 YUV420_888是YUV420的抽象格式, 它可能是YUV420p ,也可能是YUV420sp等, 这个可以通过 plane 的 getRowStride() 和 getPixelStride() 进行判断 。 我没有使用过decodeYUV420SPargb8888() ,不确定参数的具体意思, 所以请确保你传入了正确的参数。
  • 打赏
  • 举报
回复
引用 16 楼 Nature_Day 的回复:
引用 15 楼 qq_29069897 的回复:
[quote=引用 9 楼 qq_21898059 的回复:] 请问楼主camera2.0有没设置预览方向的函数啊?急求啊,谢谢
这个问题你解决了吗
求问。。。。。。[/quote] 我解决这个问题了,我用TextureView展示预览图像,设置TextureView.setRotation(),设置TextureView的角度就可以了
Nature_Day 2016-10-20
  • 打赏
  • 举报
回复
引用 15 楼 qq_29069897 的回复:
引用 9 楼 qq_21898059 的回复:
请问楼主camera2.0有没设置预览方向的函数啊?急求啊,谢谢
这个问题你解决了吗
求问。。。。。。
  • 打赏
  • 举报
回复
引用 9 楼 qq_21898059 的回复:
请问楼主camera2.0有没设置预览方向的函数啊?急求啊,谢谢
这个问题你解决了吗
_程序人生_ 2016-08-31
  • 打赏
  • 举报
回复
我也是很卡顿,请问如何解决?
Wu_Dongxia 2016-07-13
  • 打赏
  • 举报
回复
你好,可以把你的源码发给我一下吗?361722445@qq.com
yuanyanfang_ 2016-06-24
  • 打赏
  • 举报
回复
楼主问下调用系统相机拍完照之后如何才能不进入预览确认界面?应该如何设置?
Plumcot_hz 2016-03-28
  • 打赏
  • 举报
回复
引用 3 楼 CJZ_WORK 的回复:
请问楼主,你用ImageReader的回调函数获取数据会导致UI卡顿么?我就有这样的问题,不用该回调函数则预览很流畅,但是用了之后,预览卡顿很严重
我也遇到这样的问题啊,请问你解决了吗?我加了这个回调后,即使没在回调里做任何处理,还是会明显的卡顿不少
Plumcot_hz 2016-03-23
  • 打赏
  • 举报
回复
请问楼主camera2.0有没设置预览方向的函数啊?急求啊,谢谢
lzq08ms 2016-03-23
  • 打赏
  • 举报
回复
引用 9 楼 qq_21898059 的回复:
请问楼主camera2.0有没设置预览方向的函数啊?急求啊,谢谢
这个官方的sample demo里有的 你自己看下吧,和camera差不多,设置一个参数应用进去就好了 sample在media/camera2basic里有,说起来比较麻烦
zgbcumt 2015-12-13
  • 打赏
  • 举报
回复
引用 7 楼 lzq08ms 的回复:
[quote=引用 6 楼 yearningseeker 的回复:] LZ,请问一下,5.0新特性camera2 中有没有设置焦距类似的函数啊 ,我想给定一个焦距 而不是像以前一样不停地寻找 ,我想给定某个具体值,急,麻烦告知。谢谢。
float minimumLens = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE); float num = (((float) i) * minimumLens / 100); mPreviewBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, num); 同时关闭自动聚焦 需要摄像头驱动支持[/quote] 楼主意思是可以设置成类似手动调节焦距?
lzq08ms 2015-11-17
  • 打赏
  • 举报
回复
引用 6 楼 yearningseeker 的回复:
LZ,请问一下,5.0新特性camera2 中有没有设置焦距类似的函数啊 ,我想给定一个焦距 而不是像以前一样不停地寻找 ,我想给定某个具体值,急,麻烦告知。谢谢。
float minimumLens = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE); float num = (((float) i) * minimumLens / 100); mPreviewBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, num); 同时关闭自动聚焦 需要摄像头驱动支持
millyn13 2015-11-11
  • 打赏
  • 举报
回复
LZ,请问一下,5.0新特性camera2 中有没有设置焦距类似的函数啊 ,我想给定一个焦距 而不是像以前一样不停地寻找 ,我想给定某个具体值,急,麻烦告知。谢谢。
sandmangu 2015-08-31
  • 打赏
  • 举报
回复
android camera一般会出yuv420的图吗, 一般不是yuv422的吗? 换个输出格式看看?
lzq08ms 2015-08-25
  • 打赏
  • 举报
回复
引用 3 楼 CJZ_WORK 的回复:
请问楼主,你用ImageReader的回调函数获取数据会导致UI卡顿么?我就有这样的问题,不用该回调函数则预览很流畅,但是用了之后,预览卡顿很严重
过了蛮久才回来看的 只要不对获取的数据进行java层处理就不卡顿 java处理大循环还是费力
CJZ_WORK 2015-08-18
  • 打赏
  • 举报
回复
请问楼主,你用ImageReader的回调函数获取数据会导致UI卡顿么?我就有这样的问题,不用该回调函数则预览很流畅,但是用了之后,预览卡顿很严重
再见沙华 2015-06-29
  • 打赏
  • 举报
回复
YUV_420_888和YUV420格式还是不一样的,有区别。所以decodeYUV420SPargb8888这个格式转换函数不一定适用。
lzq08ms 2015-05-28
  • 打赏
  • 举报
回复
每人能帮忙么?顶一下咯

80,472

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧