Android相机开发系列
Android Camera Develop Series
简介
Android相机开发系列文章循序渐进,教你从一个没有任何功能的相机APP开始,逐步完善实现一般相机APP的各种功能,甚至还能拿来做图像处理。系列文章力求简单精炼,以快速上手,理解原理为目的;且每篇均提供DEMO源码,以供参考。
写作Android相机开发系列的原因一是看到目前系统介绍Android相机开发的文章寥寥无几,二是有些文章示例代码过于老旧不再适合学习。本系列文章主要以API Level 19 (Android 4.4)为目标等级,以Android官方文档为参考,力求与时俱进、逻辑通顺。
希望本系列文章能够对你有所帮助。
目录
- Android相机开发(一):最简单的相机
- Android相机开发(二): 给相机加上偏好设置
- Android相机开发(三): 实现拍照录像和查看
- Android相机开发(四): 旋转与纵横比
- Android相机开发(五): 触摸对焦,触摸测光,二指手势缩放
- Android相机开发(六): 高效实时处理预览帧数据
后记
目前为止Android相机开发系列已经写了6篇,几乎涵盖了一般相机APP的所有功能,算是功德圆满了。最初接触Android相机其实是因为需要做基于Android的实时图像处理的APP,在磕磕绊绊中基本达到了预期目标。回首从刚接触Android到实现一个高性能的复杂APP,走了很多的弯路也踩了很多坑,当然也得到了许多人的帮助,想想如果我把自己学到的东西分享出来,也未免太卑鄙了。于是就从自己最擅长的Android相机开发着手,也就有了此系列文章。
赠人玫瑰,手有余香。
请问我的app拍照预览没有问题,点击录像以后预览画面卡住但是录像还在进行,查看保存的录像发现是一段完整的视频,只是录像的预览画面没有显示,纠结了好几天了没发现问题。运行到mMediaRecorder.start()就卡住了,好像mMediaRecorder.setPreviewDisplay(mHolder.getSurface())没有起到作用,会不会是安卓系统版本问题,我用的是9.1的手机运行的?
你好博主,我想问下怎么实现保存图片和视频到本地呢?编程小白,第一次接触java,博主能具体点告知下吗,万分感谢
你好,我在预览的时候是自定义的宽高,然后开启录像,录像的宽高就发生了变化,应该是调用了camera的reset导致的,这个有办法解决吗?
这是因为你调用了录像的API,而录像的分辨率和预览的分辨率是独立的(你可以看第二篇文章关于偏好设置里面,有预览分辨率和视频分辨率),需要注意的是预览分辨率和录像分辨率可能不是一一对应的,而你需要做的是加上mMediaRecorder.setVideoSize()这个方法的调用,设置录像的分辨率。
你好,请问下 我想实现一个矩形框部分录像的功能不知道你有什么好的方案或者建议之类的吗?就是类似照相机中有一个矩形框 拍出来是矩形框中的部分照片一样,实现部分录像的功能
你好,抱歉回复晚了。你可以理解成相机拿到的每帧都是一个二维矩阵,你想要其中的矩形部分就直接只要矩阵中的一部分就好啦。说到细节的话其实就挺繁琐了,录像的API和相机预览的API不同,不能拿到每帧的数据,另外如果拿到的是每帧的数据,那还要考虑用适当的编码器来将这些帧合成为视频。我的思路有三个,一个是用录像的API,看看有没有满足你的要求的方法能够设置;另外就是用相机预览的API,这时就要考虑到效率问题,避免遍历矩阵,也要避免占用过多内存;最后就是直接对拍到的视频文件进行处理,从效率考虑就需要硬件编码解码之类的。
博主,这个系列写的太好了,为什么早没搜到。T^T
可以请教个问题吗,最近工作需求,拍照时识别到卡片就自动拍照,这个问题困扰我一周了快。
是想做自动识别银行卡卡号的功能,但是现在不做那么复杂,只要识别到卡片后,自动拍照,然后再把照片传给阿里服务器去解析。类似微信的识别银行卡、扫一扫之类的功能。
望博主回复,感谢T……T。
这个你可以参考OpenCV给的Android DEMO,那里有个实时人脸识别和边界识别的APP。其实...你想做的简单点的话,每秒上传一两个帧到服务器上,有没有卡片或者卡片是不是银行卡都交给服务器好了。然后如果你想本地识别出有没有卡片的话,还是需要一些图像处理的基础的,最简单的就是把图片二值化,看有没有一个黑色的矩形区域。
感谢博主大大回复!
其实也不用做到识别出卡片,只要是个矩形在我照相机的矩形框里,我就自动拍照就好了,因为图片上传到阿里是要收费的,如果图片背景很杂,阿里就识别不出卡号,所以在客户端尽量保证图片的质量。
我先去看看OpenCV的Android Demo和图片二值化,感谢博主给出思路T^T。有不懂的我还会再回来的0.0
博主你好,首先谢谢您写的这么好的文章,我有个问题想请问下,摄像头权限在第一次访问app的时候会向用户发送是否打开摄像头权限的一个弹出框,但是我如果手动去把摄像头权限设置为禁止之后,后面会直接打不开app直接闪退是什么原因呢?怎么才能做到即使用户手动设置禁用app权限之后还能够打开app并且向用户申请打开摄像头权限呢?才接触安卓,很多东西都不知道
这个是动态权限的问题,因为太忙一直没有更新。如果出现因为摄像头的闪退,你需要在设置里手动把APP的摄像头权限打开。
因为现在的代码并未检查动态权限直接获取摄像头,所以如果获取时实际没有拿到摄像头权限,就会闪退。解决的方法是在获取前加入动态权限检查,如果没有拿到权限就等待用户授权,或者放弃摄像头;刚接触的话你可以先在设置中给好摄像头权限,等熟悉了仔细看看Android 6.0引入的动态权限机制。
首先感谢博主,这也许是我找到的最完整最全面最易懂的android相机开发教程。从你的文字中我真的收获很多。由于工作的原因,最近在着手开发一个应用,之前是调用系统拍照接口,但易用性不是很高,所以打算重新弄一个,然后就搜到你的文字,现在自己的小项目在稳步推进中。
很高兴能够帮到你 ^_^
请问在开发的时候,有遇到过改变video分辨率的时候,录像过程会发生图像拉伸的情况,该怎么处理呢
抱歉回复晚了,理论上来说是不可能的吧。getSupportedVideoSizes()可以拿到支持的录像分辨率,照这个设置了拍照就没问题的;我遇到的图像变形都是因为预览和屏幕尺寸不一致造成的,这个在我的第四篇文章里专门讲过的。
谢谢你的回复,在相机预览的时候,如果不把surfaceview长宽比和PreviewSize比例一样的话,预览的时候不会变形吗,我仔细看了一下,你好像没有相关的设置。我getSupportVideoSize后得到的支持分辨率的尺寸比例基本上是4:3,16:9,3:2的,但如果surfaceview长宽比和VideoSize比例不一样,就会发生变形,也就是说,现在我必须把surfaceview,PreviewSize,VideoSize比例设置的都一样才能保证录制过程没有变形,,,困扰很久了,有点找错问题方向的感觉
按照官方文档里的推荐,你需要根据设置的videosize选择相同ratio(纵横比)的previewsize,然后把previewsize应用到camera,最后调整surfaceview,让surfaceview和previewsize的ratio相同,这样在录像时预览就看起来是正常的了。
那就是说每变一次VideoSize,surfaceview的大小就要变一次是吗。这样体验就不太好了,而且系统相机就没有这个问题。
我刚才看了下华为的自带相机,拍照和录像是分开的,滑动来切换。切换时surfaceview的大小同时改变了,由适应拍照的previewsize改为了适应录像的previewsize;同时camera的preview参数也调整为video的分辨率参数(即分辨率降低了)。在设置video分辨率的时候,点击不同的分辨率,surfacesize会马上变化,华为做了个动画来过渡。所以不太清楚你说的体验不好的意思,或者是我理解错了?
你说的没问题
我想請問一下,要如何從Android相机开发(六)處理幀數據,那裏取得每個frame畫面的pixel矩陣並印出
你好,不是太明白你的意思。相机开发(六)中介绍的就是取得每个frame的数据,是一个byte[]类型,并且数据格式是NV21;想要理解为矩阵的话,byte[]就是按行存储的,对于分辨率为w*h的帧,就是以wwwww存储的,这个没啥问题吧?把byte[]打印出来就是自己根据分辨率写个两层循环了,如果是保存为图片还请参考我的另一篇文章。