~转载请注明http://blog.csdn.net/u013015161/article/details/46921257
介绍
这几天,写了一个自定义照相机的demo,支持连续拍照和摄像头切换。由于自己以前没接触过相关的编程,也算是一个学习的过程,在这里做一下记录,同时也分享出来,并附上源码和工程。
效果如图:
左上角switch切换摄像头,右边snap按钮进行拍照。
一般流程
Android进行拍照,需要调用摄像头类android.hardware.Camera。而要进行预览,则需要用android.view.SurfaceView对每一帧的预览图进行显示。
实现自定义相机一般流程为:
1、用addCallback给SurfaceView设置Callback接口对象,实现其中三个回调方法:surfaceCreated、surfaceChanged、surfaceDestroyed。
在surfaceCreated中打开摄像头,获得Camera对象,并设置其在surfaceview上预览;
在surfaceChanged中设置摄像头的参数;
在surfaceDestroyed释放摄像头,否则会导致退出之后其他应用无法调用摄像头,包括系统相机。
2、点击拍照按钮时,调用Camera对象的takePicture方法,其第三个参数为PictureCallback接口对象,其中的onPictureTaken回调方法参数中有一个byte数组,存储了拍摄到的图片数据,在方法中保存到本地即可。
这样,一个基本可用、带预览的自定义相机就做好了。但这样还远远不够,因为会出现各种各样的问题。
主要问题
预览变形
这个是最头疼的问题。首先要知道3个宽高比:摄像头分辨率(PictureSize)宽高比、预览分辨率(PreviewSize)宽高比以及用作预览的SurfaceView的宽高比。如果要让预览不变形,这三个宽高比需要保持一致。这种一致性的保持在设置摄像头参数时进行。代码如下:
public void setCameraAndDisplay(int width, int height)
{
Camera.Parameters parameters = camera.getParameters();
/*获取摄像头支持的PictureSize列表*/
List<Camera.Size> pictureSizeList = parameters.getSupportedPictureSizes();
/*从列表中选取合适的分辨率*/
Size picSize = CameraUtils.getProperSize(pictureSizeList, ((float)width)/height);
if(null != picSize)
{
parameters.setPictureSize(picSize.width, picSize.height);
}
else
{
picSize = parameters.getPictureSize();
}
/*获取摄像头支持的PreviewSize列表*/
List<Cam