相机开发(聚焦、横竖屏拍照、照片存储、连续拍照等)

最近项目用到了相机拍照的功能,于是想着封装好一些通用性较好的相机调用,从百度和谷歌上查找出来的资料真的印证了“天下文章一大抄”的道理,而且它们实现的拍照功能大都存在缺陷,如聚焦问题、重复拍照问题、照片存储问题、横竖屏转换问题。一大堆的问题,而且程序的扩展性和可重用性实在不敢恭维,排版级其混乱。最后无奈,打开API文档camera相机类,从最基础的学起,然后自己进行改进,从这里也告诉我们一个道理
摘要由CSDN通过智能技术生成

最近项目用到了相机拍照的功能,于是想着封装好一些通用性较好的相机调用,从百度和谷歌上查找出来的资料真的印证了“天下文章一大抄”的道理,而且它们实现的拍照功能大都存在缺陷,如聚焦问题、重复拍照问题、照片存储问题、横竖屏转换问题。一大堆的问题,而且程序的扩展性和可重用性实在不敢恭维,排版级其混乱。

最后无奈,打开API文档camera相机类,从最基础的学起,然后自己进行改进,从这里也告诉我们一个道理,API文档才是学习起点,因为它会告诉你整个实现的原理和原因,能够对整个框架有一个整体的了解,看完API文档看其他的就有事半功倍的效果,吐槽完毕,下面来正式实现。

一.实现流程

这幅图是从API文档(最好是看英文版的)整理出来的,从这副图上面我们可以看出,主要是有6步,其中难点是创建相机预览类。


二.权限声明

       这个不讲了,直接加入声明权限代码,不明白的可以网上查查看

        <uses-permission android:name="android.permission.CAMERA" />
	<uses-feature android:name="android.hardware.camera" />
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
	<uses-feature android:name="android.hardware.camera.autofocus" />
	<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

三 检查相机和获取相机实例

        新建CameraCheck类,主要有2个方法,代码如下

public class CameraCheck {

	public static boolean CheckCamera(Context mContext) {
		if (mContext.getPackageManager().hasSystemFeature(
				PackageManager.FEATURE_CAMERA)) {
			return true;
		} else {
			Toast.makeText(mContext, "相机不存在!", Toast.LENGTH_SHORT).show();
			return false;
		}
	}

	/** A safe way to get an instance of the Camera object. */
	public static Camera getCameraInstance(Context mContext) {
		Camera c = null;
		if (CheckCamera(mContext)) {
			try {
				c = Camera.open();
			} catch (Exception e) {
				c=null;
			}
		}
		return c; // returns null if camera is unavailable
	}
}

第一个方法用来检查相机是否存在,这个方法是来自API文档,使用方法

mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)

hasSystemFeature(String name)方法返回设备是否支持name功能的真假值;

通过方法getCameraInstance返回相机的实例,通过调用该方法,mContext能够获得该相机资源,只有获得了该相机资源才能够对相机进行操作。

 

四.创建相机预览类(重点)

        我们在拍照之前需要对取景进行预览,这里我们需要使用SurfaceView控件,关于SurfaceView控件我们先简单的了解一下(别急,磨刀不误砍柴工)。

   SurfaceView是View的子类,所以它拥有View的一切方法和属性,这一点我们从命名上面就可以看出来,比如绘制方法、大小等属性;它比View多了一个Surface的东西,Surface是专门用来绘制的类,而SurfaceView可以控制surface绘制的大小、位置等等;

可能有人会问,那为什么要专门这样一个类来绘制呢?不是有OnDraw()方法吗?相比于OnDraw()方法它有很多优势,如下总结:

  (1)在频繁更新UI线程的情况下,可以使用封装好的surface来频繁的更新,因为surface可以使用后台线程对UI界面进行绘制,而OnDraw()等绘制方法很难做到(除非你频繁的调用handler来更新主界面,这得多麻烦啊!);

(2)SurfaceView可以用来绘制2D或者3D图形,绘制一些动态曲线等,它显示的速度会比一般的快很多,因为他是通过硬件加速的方式来绘制的。

(3)它可以用来接受硬件的数据来绘制图像。

所以,通过以上几点我们可以知道,用它来接受相机的预览是理所当然的。那么它的使用方法是怎么样的呢?下创建一个surfaceView的继承类一般需要实现如下几个方法:

    (1)surfaceCreated(SurfaceHolderholder):在该类创建的时候调用,这里一般需要实现一些初始化的工作,SurfaceHodler用来设定surface的大小位置等等;

   (2)surfaceChanged(SurfaceHolderholder, int format, int width,int height)在surface大小发生改变时候调用,这里实现图形的绘制;

(3)surfaceDestroyed(SurfaceHolderholder)在surface销毁时候调用,这里一般对资源进行释放&

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值