在讲解ImageReader之前,我们先看一段代码
/**
* 初始化图片读取器
*/
private void initImageReader() {
//创建图片读取器,参数为分辨率宽度和高度/图片格式/需要缓存几张图片,我这里写的2意思是获取2张照片
mImageReader = ImageReader.newInstance(1080, 1920, ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
// image.acquireLatestImage();//从ImageReader的队列中获取最新的image,删除旧的
// image.acquireNextImage();//从ImageReader的队列中获取下一个图像,如果返回null没有新图像可用
Image image = reader.acquireNextImage();
try {
File path = new File(Camera2Activity.this.getExternalCacheDir().getPath());
if (!path.exists()) {
Log.e(TAG, "onImageAvailable: 路径不存在");
path.mkdirs();
} else {
Log.e(TAG, "onImageAvailable: 路径存在");
}
File file = new File(path, "demo.jpg");
FileOutputStream fileOutputStream = new FileOutputStream(file);
// 这里的image.getPlanes()[0]其实是图层的意思,因为我的图片格式是JPEG只有一层所以是geiPlanes()[0],如果你是其他格式(例如png)的图片会有多个图层,就可以获取指定图层的图像数据
ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
fileOutputStream.write(bytes);
fileOutputStream.flush();
fileOutputStream.close();
image.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}, mChildHandler);
}
分析上面的代码:
ImageReader类允许应用程序直接访问呈现表面的图像数据
创建ImageReader对像
ImageReader ir = ImageReader.newInstance(int width, int height, int format, int maxImages);
参数:
- 默认图像的宽度像素
- 默认图像的高度像素
- 图像的格式
- 用户想要读图像的最大数量
ImageReader类的主要操作:
- getSurface() //得到一个表面,可用于生产这个ImageReader图像
- acquireLatestImage() //从ImageReader的队列获得最新的图像,放弃旧的图像。
- acquireNextImage() //从ImageReader的队列获取下一个图像
- getMaxImages() //最大数量的图像
- getWidth() //每个图像的宽度,以像素为单位。
- getHeight() //每个图像的高度,以像素为单位。
- getImageFormat() //图像格式。
- close() //释放与此ImageReader相关的所有资源。用完记得关