首先说明一下,标题中的“相机”指的是Android原生接口Camera,“回调数据”指的是通过对Camera实例设置预览回调获取的数据:

camera.setPreviewCallback(new Camera.PreviewCallback() {            @Override            public void onPreviewFrame(byte[] data, Camera camera) {                               }        });

“解析”是指这里的byte[]数据无法直接保存为图片供我们使用,所以需要转码为我们常用的图片编码数据。这里先给出方法,再说明原因

 YuvImage image = new YuvImage(data, ImageFormat.NV21, width, height, null); ByteArrayOutputStream stream = new ByteArrayOutputStream(); image.compressToJpeg(new Rect(0, 0, width, height), value, stream); byte[] newData=stream.toByteArray();

注:上述中的data就是回调的原始数据,newData就是转换后的数据。宽高对应为预览的宽高数据,value是图片质量数值;这样转换之后就可以通过新的数据进行各种操作,保存为图片,转为bitmap等等。

 

下面说明一下原因,可以选择不看;我们知道,Camera在使用的时候,我们可以通过获取Camera中的支持的各种参数用于我们的个性化设置:

Camera.Parameters params = mCamera.getParameters();

我们从params中可以读取当前Camera支持的预览尺寸列表,预览格式,拍照格式,闪光灯模式,白平衡,颜色效果等等,如:

 params.getSupportedPictureFormats(); params.getSupportedPreviewFormats(); params.getColorEffect(); params.getWhiteBalance(); params.getFlashMode(); .........

ok,我们重点关注数据类型,我们知道上面的原始数据来源于预览回调,所以我们重点查看Camera支持的预览数据格式,也即:

 List list = params.getSupportedPreviewFormats();

返回的是一个List列表,其中的元素是整形,其中的数值对应到ImageFormat类中定义的常量,我们调用上述方法可以查看当前摄像头支持的预览数据格式,可以通过下面的接口方法修改摄像头支持的预览格式:

 params.setPreviewFormat(ImageFormat.NV21); mCamera.setParameters(params);

默认的格式就是NV21的,因为基本所以摄像头都支持该种格式,我们这个时候再回到上面的处理逻辑上:

YuvImage image = new YuvImage(data, ImageFormat.NV21, width, height, null);

这里的YuvImage API专门用于处理YUV编码的数据,我们先看一下文档介绍:

* YuvImage contains YUV data and provides a method that compresses a region of* the YUV data to a Jpeg. The YUV data should be provided as a single byte* array irrespective of the number of image planes in it.* Currently only ImageFormat.NV21 and ImageFormat.YUY2 are supported.

YuvImage内部包含有YUV编码数据,并且提供方法把这种转换为一张Jpeg图片。目前只支持ImageFormat.NV21与ImageFormat.YUY2类型的YUV数据

我们知道YUV编码指的是一个类别,其中有很多种颜色编码格式,主要用于视频处理上,关于这块可以自行百度一下。上述通过预览的元素数据以及预览的宽高和格式就可以构建出一个YuvImage实例,我们在上面的文档中了解到,这个类中提供了把YUV数据转换为Jpeg图片的方法:

image.compressToJpeg(new Rect(0, 0, width, height), value, stream);

这个就实现了原始YUV数据到图片数据流的转换功能。其实到这里我们一直有一个疑惑,那就是我们可以把byte[]数据通过BitmapFactory中接口直接转为Bitmap数据,或者直接把原始的YUV数据data写到图片文件中,实际上这样操作的结果就是下列接口获取的Bitmap为空,图片文件也不能正常使用

 Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
private void bytesToImageFile(byte[] data) {        try {            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/why.jpeg");            FileOutputStream fos = new FileOutputStream(file);            fos.write(data, 0, bytes.length);            fos.flush();            fos.close();        } catch (Exception e) {            e.printStackTrace();        }

主要原因还是编码的问题,就好比是写了一篇作文,转化为16进制字符串保存为文件传给你的老师,他在没有转码的情况下觉得你的作文有问题;或者我用base64对其解码肯定也是不行的。本篇内容其实很单薄也很简单,但是在不了解的情况下还是会遇到这样的问题,一般遇到之后我们都会搜索byte[]数据与Bitmap,File等等之间的转换实现,但是在原始数据不转码的情况下,网上的工具类方法都是无法使用的。其实这里还有一种方法获取JPEG的byte数据,那就是通过回调回来的Camera的takePicture()接口实现:

 camera.takePicture(new Camera.ShutterCallback() {                    @Override                    public void onShutter() {                    }                }, new Camera.PictureCallback() {                    @Override                    public void onPictureTaken(byte[] data, Camera camera) {                     //data和预览的data一样                    }                }, new Camera.PictureCallback() {                    @Override                    public void onPictureTaken(byte[] data, Camera camera) {                      //data可以直接保存jpeg类型图片或者转为Bitmap都可以                      }                });

上面的方式就是内部做了转换。

注:欢迎扫码关注

 

 

更多相关文章

  1. “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
  2. Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
  3. 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
  4. [Android][MediaRecorder] Android(安卓)MediaRecorder框架简洁
  5. android 10 手机无法预览到图片, 加载图片, 无法显示图片内容问
  6. android开发实例05:新浪微博图片缩放实现
  7. android将图片转成字符串,再将字符串转成图片 (base64处理的字符
  8. Android(安卓)的动作、广播、类别等标识大全
  9. Android中ListView动态添加删除项

随机推荐

  1. android 使用Lottie实现Android动画
  2. Android中onContextItemSelected不响应
  3. android开发 列表显示(ListView)
  4. Android导出文件位置讨论
  5. Android 后台任务(五)Service
  6. Android布局(序章)
  7. Android异步下载网络图片(其一)
  8. Android ROM的创建和烧录
  9. Android(安卓)Activity的生命周期
  10. android资料--Android通过手势(多点)缩放和