做VR产品的时候,有个产品的目标是做一个左右眼的摄像头,实现两个摄像头采集数据,左右分屏的显示在手机屏幕上,当时调研发现,手机因为只有一颗ISP所有一般情况下只能打开一个摄像头,所以当时考虑可以使用手机的摄像头外接一个USB camera。由于当时时间比较紧,所以调研过程中只做了屏幕的分屏显示,而没有做摄像头的输入方式。
当时采用的方法是修改图形显卡(framebuffer)的参数,使得图像在输出的时候能够左右分屏,但是不同的平台下也会出现有的能work有的不work的情况。
所以到现在也没有很好的解决方案。
最近在学习camera相关知识的时候假想了一种使用场景,使用单个摄像头完成摄像头图像的复制,做一个类似左右眼的效果。
设定的方法是在布局文件中设定一个surfaceView和一个ImageView:
记得之前描述过,我们可以通过onPreviewFrame回调函数拿到data数据。既然如此,我们便可以把这部分数据复制到一份显示在屏幕上,实现左右分屏。
要注意的是,此处返回的数组图像格式为NV21(YUV420SP),并不支持直接BitmapFactory.decodeByteArray()方法,需要进行格式转换。参考网上的博客https://blog.csdn.net/d276031034/article/details/73276495
//将rawImage转换成bitmap
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
最终调用icon.setImageBitmap(bitmap); 将图像显示出来。
但是正如原作者所说,显示的延时现象很明显。
可以参考网上的多线程的优化方式,https://www.2cto.com/kf/201605/511009.htmlAndroid性能优化典范之多线程篇
我们可以使用HandlerThread的方式来进行实现,
//创建一个HandlerThread并启动
mHandlerThread=new HandlerThread(“my_handlerthread”);
mHandlerThread.start();
创建handler来启动我们定义的任务
subHandler=new Handler(mHandlerThread.getLooper());
subHandler.post(newMyTask());
在MyTask中实现具体功能:
classMyTaskimplementsRunnable{
@SuppressLint(“NewApi”)@Override
public void run(){
doChange(surfaceView.getHolder());
}
}