Android Camera添加预览水印

  • 内容
  • 评论
  • 相关

前言

SurfaceView初步以及Camera初步中我介绍了如何使用SurfaceView以及如何使用SurfaceView来预览Camera画面,接下来我就来介绍下如何给Camera添加水印效果。由于SurfaceView不支持回显,也就是将摄像头捕获到的数据处理以后重新设置到界面上,所以我会使用两个SurfaceView来介绍。

思路

我们想给预览界面添加水印第一步肯定是需要获取到每一帧的数据然后处理完以后再绘制到界面上,Android为Camera提供了两个接口用于获取每一帧的数据。分别如下

第一种方式:setPreviewCallback方法,设置回调接口:PreviewCallback

在回调方法:onPreviewFrame(byte[] data, Camera camera) 中处理每一帧数据

第二种方式:setPreviewCallbackWithBuffer方法,同样设置回调接口:PreviewCallback,不过还需要一个方法配合使用:addCallbackBuffer,这个方法接受一个byte数组。

第二种方式和第一种方式唯一的区别:

第一种方式是onPreviewFrame回调方法会在每一帧数据准备好了就调用,但是第二种方式是在需要在前一帧的onPreviewFrame方法中调用addCallbackBuffer方法,下一帧的onPreviewFrame才会调用,同时addCallbackBuffer方法的参数的byte数据就是每一帧的原数据。所以这么一看就好理解了,就是第一种方法的onPreviewFrame调用是不可控制的,就是每一帧数据准备好了就回调,但是第二种方法是可控的,我们通过addCallbackBuffer的调用来控制onPreviewFrame的回调机制。

注意:

因为第二种方式在调用的时候有点注意的地方:

1、在调用Camera.startPreview()接口前,我们需要setPreviewCallbackWithBuffer,而setPreviewCallbackWithBuffer之前我们需要重新addCallbackBuffer,因为setPreviewCallbackWithBuffer 使用时需要指定一个字节数组作为缓冲区,用于预览图像数据 即addCallbackBuffer,然后你在onPerviewFrame中的data才会有值。

2、从上面看来,我们设置addCallbackBuffer的地方有两个,一个是在startPreview之前,一个是在onPreviewFrame中,这两个都需要调用,如果在onPreviewFrame中不调用,那么,就无法继续回调到onPreviewFrame中了

编码

当我们设置好回调接口以后就可以在里面获取到数据了,不过这里的数据默认为NV21格式,所以我们需要转换为图像才行。

上面的代码中,我首先将NV21类型的数据转为Image,然后获取预览SurfaceView的Canvas,然后将处理的结果绘制上去即可。关于图片的旋转以及添加水印,可以参考Android绘图基本操作。http://27house.cn/archives/405

图片处理操作如下,主要是将图片旋转了90°,关于旋转的原因请查看上篇博客Camera初步,然后绘制水印以及时间戳。

Demo下载地址:https://github.com/CB2Git/BlogDemoRepository

参考链接:http://www.wjdiankong.cn

评论

0条评论

发表评论

邮箱地址不会被公开。