ImageReader
2019-02-10 本文已影响0人
小斌_bingor
- 这个系列的文章会翻译跟Camera2相关的api(用我的散装英语+自己的理解)
- 目前处于一边学习一边翻译的状态,所以可能会有错误
- 我也还没做校对,有需要的凑合着看,我会一边写一边回顾,有错就改
- 也请路过的大神斧正,感谢~~~
ImageReader其实并不是专供Camera使用的一个类,由于Camera2采用管道的形式来构建,那么,自然而然地需要使用数据流这样一个概念
ImageReader这个类被允许直接从Surface接收渲染的图像数据
有好几个类都会接收Surface对象的数据去进行渲染,每种来源可以使用的图像大小和格式各不相同,所以使用的时候应该去API文档查一下
可以同时访问多个Image,但不能超过maxImages
如果ImageReader获取并销毁图像的速度小于数据源产生数据的速度,那么就会丢帧
嵌套类
ImageReader.OnImageAvailableListener
通知有新图像可用的回调
公开方法
//从ImageReader的队列里面,获取最新的Image,删除旧的,如果没有可用的Image,返回null
//推荐使用acquireNextImage(),大多数场景下更适合实时处理
//过多的调用acquireLatestImage()(大于getMaxImages()),而没有调用Image.close()的话,将会抛出IllegalStateException
public Image acquireLatestImage ()
//获取下一个最新的可用Image,没有则返回null
//建议对批处理/后台处理使用acquireNextImage()
//过多的调用acquireLatestImage()(大于getMaxImages()),而没有调用Image.close()的话,将会抛出IllegalStateException
public Image acquireNextImage ()
//释放与此ImageReader关联的所有资源。
//调用close()之后,这个ImageReader就失效了,无法再调用任何方法,尝试再次读取Image的话,将抛出IllegalStateException
public void close ()
//获取Image的默认高度,单位是像素
//这个高度有可能被改写,可以用Image.getHeight()获取Image的实际高度
public int getHeight ()
//获取Image的默认宽度,单位是像素
//The width may be overridden by the producer sending buffers to this ImageReader's Surface.
//生产者(大概指的摄像头?)向ImageReader对应的Surface发送缓冲区,会覆盖宽度
//可以用Image.getHeight()获取Image的实际高度
public int getWidth ()
//获取Image的格式
public int getImageFormat ()
//任意时刻可获取的最大Image数量
//一个Image被获取方法(acquireLatestImage ()或者acquireNextImage ())返回之后,即被认为是已获取,直到该Image被close(),释放回ImageReader
//不应获取超出getMaxImages ()数量的Image,会抛出IllegalStateException
//Furthermore, while the max number of images have been acquired by the ImageReader user, the producer enqueueing additional images may stall until at least one image has been released.
//这句翻译不来,大意是获取了最大数量的Image,ImageReader的队列可能会停止入列,直到用户释放至少一个Image资源?
public int getMaxImages ()
//获取为当前ImageReader生产Image的Surface
//在有效的Image数据被渲染到Surface之前,acquireNextImage()将返回null
//同一时间,只能有一个源向Surface输送数据,但是断连之后,该Surface可被其他的源重用
public Surface getSurface ()
//按照你期望的尺寸和格式新建一个ImageReader
//maxImages参数指定了能从ImageReader获取Image对象的最大值,过多获取缓冲区可能导致OOM,所以最好按照最少的需要去设置这个值
//图像真正的格式和大小取决于它的来源(应该就是说的摄像头咯)
//如果图像的格式是PRIVATE的,那么将产生程序无法直接访问的Image(那该怎么处理呢?文档也没说),Image的getPlanes()方法也会返回一个空数组
//私有格式与使用其他格式(如YUV_420_888)的ImageReader相比,当不需要应用程序访问图像数据时,ImageReader的使用效率更高。
public static ImageReader newInstance (int width, int height, int format, int maxImages)
//添加新图像可用回调
//@params handler 如果你喜欢回调在你指定的线程里面去执行,就指定handler,不然就传空,回调会在当前线程里面去执行
//当没有传handler并且调用线程没有looper的时候,抛出IllegalArgumentExeption
public void setOnImageAvailableListener (ImageReader.OnImageAvailableListener listener, Handler handler)