Android中开发相机的两种方式
Android系统提供了两种使用手机相机资源实现拍摄功能的方法,一种是直接通过Intent调用系统相机组件 + startActivityForResult得到相机拍照结果,这种方法快速方便,适用于直接获得照片的场景,如上传相册,微博、朋友圈发照片等。另一种是使用相机API来定制自定义相机,这种方法适用于需要定制相机界面或者开发特殊相机功能的场景,如需要对照片做裁剪、滤镜处理,添加贴纸,表情,地点标签等。
调用系统自带相机
关于系统自带相机的调用非常简单,具体可以参考谷歌的Training。我只说容易被大家忽视的几个点:
-
如果我们的应用使用相机,但相机并不是应用的正常运行所必不可少的组件,可以将权限声明中的android:required设置为”false”。这样的话,Google Play 也会允许没有相机的设备下载该应用。当然我们有必要在使用相机之前通过调用hasSystemFeature(PackageManager.FEATURE_CAMERA)方法来检查设备上是否有相机。如果没有,我们应该禁用和相机相关的功能!
-
在调用startActivityForResult()方法之前,先调用resolveActivity(),这个方法会返回能处理该Intent的第一个Activity(译注:即检查有没有能处理这个Intent的Activity)。执行这个检查非常重要,因为如果在调用startActivityForResult()时,没有应用能处理你的Intent,应用将会崩溃。所以只要返回结果不为null,使用该Intent就是安全的。
使用Android框架所提供的API来直接控制相机硬件
使用API来控制相机我们需要用到关键类和接口:
- 使用Camera对象来控制相机
- 使用SurfaceView或TextureView来展现照相机采集的图像
- 通过surfaceholder来控制surface的尺寸和格式,修改surface的像素,监视surface的变化等等
- 通过SurfaceHolder.Callback 接口,监听surface状态变化
API说明
Camera :最主要的类,用于管理和操作camera资源。它提供了完整的相机底层接口,支持相机资源切换,设置预览/拍摄尺寸,设定光圈、曝光、聚焦等相关参数,获取预览/拍摄帧数据等功能,主要方法有以下这些:
- open():获取camera实例。
- setPreviewDisplay(SurfaceHolder):绑定绘制预览图像的surface。surface是指向屏幕窗口原始图像缓冲区(raw buffer)的一个句柄,通过它可以获得这块屏幕上对应的canvas,进而完成在屏幕上绘制View的工作。通过surfaceHolder可以将Camera和surface连接起来,当camera和surface连接后,camera获得的预览帧数据就可以通过surface显示在屏幕上了。
- setPrameters设置相机参数,包括前后摄像头,闪光灯模式、聚焦模式、预览和拍照尺寸等。
- startPreview():开始预览,将camera底层硬件传来的预览帧数据显示在绑定的surface上。
- stopPreview():停止预览,关闭camra底层的帧数据传递以及surface上的绘制。
- release():释放Camera实例
- takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg):这个是实现相机拍照的主要方法,包含了三个回调参数。shutter是快门按下时的回调,raw是获取拍照原始数据的回调,jpeg是获取经过压缩成jpg格式的图像数据的回调。
SurfaceView :用于绘制相机预览图像的类,提供给用户实时的预览图像。普通的view以及派生类都是共享同一个surface的,所有的绘制都必须在UI线程中进行。而surfaceview是一种比较特殊的view,它并不与其他普通view共享surface,而是在内部持有了一个独立的surface,surfaceview负责管理这个surface的格式、尺寸以及显示位置。由于UI线程还要同时处理其他交互逻辑,因此对view的更新速度和帧率无法保证,而surfaceview由于持有一个独立的surface,因而可以在独立的线程中进行绘制&#x