name="android.permission.ACCESS_FINE_LOCATION"/>
3、使用方法
使用摄像头的方法有两种:
一种是编写代码比较少的,快速使用摄像头的意图Intent方法;
另外一种就是自动外观的摄像头用户界面,要求编写更多的代码。
4、使用Intent快速应用摄像头:
使用默认配置拍摄并保存
/*
*前置摄像头抓拍
**/
/*--------------------------摄像头程序-begin--------------------------------*/
camera_catch.setOnClickListener(newOnClickListener()
{
@Override
publicvoidonClick(Viewsource)
{
Intentcapture_intent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE);
//创建一个文件来保存图片
Fileout=newFile(capture_path);
//转换为URI地址
Uriuri=Uri.fromFile(out);
//设置图片保存
capture_intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);
//图片质量为高
capture_intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,1);
//启动拍照意图
startActivityForResult(capture_intent,CAPTURE_REQUEST_CODE);
}
});
}
/*
*拍照,并保存数据,通过重写onActivityResult方法去返回处理结果给主main:
RFID
**/
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata)
{
//重写父类方法
super.onActivityResult(requestCode,resultCode,data);
if(requestCode==CAPTURE_REQUEST_CODE)//判断是摄像头请求
{
if(resultCode==RESULT_OK)
{
//拍照图像显示
Bitmapcapture_bm=(Bitmap)data.getExtras().get("data");
p1_image.setImageBitmap(capture_bm);
FilecaptureFile=newFile(capture_path);
try{
BufferedOutputStreambos=newBufferedOutputStream(
newFileOutputStream(captureFile));
capture_press(Bitmap.CompressFormat.JPEG,100,bos);
bos.flush();
bos.close();
}catch(Exceptione){
//TODO:
handleexception
Toast.makeText(this,"没有找到照片文件",1000).show();
}
}
}
}
/*--------------------------摄像头程序-end--------------------------------*/
5、自定义摄像头:
预览、聚焦后才拍摄
主要步骤如下:
(1)调用Camera的open()方法打开相机,该方法默认打开后置摄像头,如果打开前置摄像头,就必须获得前置摄像头的ID,然后传入该ID;(一般后置ID是0,前置是1,Android2.3(APILevel9)以上版本允许利用Camera.getNumberOfCameras()方法来检查设备可用摄像头的数量)
可用Camera.open()方法来访问主摄像头,并确保捕获全部的异常,示例代码如下:
/**安全获取Camera对象实例的方法*/
publicstaticCameragetCameraInstance(){
Camerac=null;
try{
c=Camera.open(intID);//试图获取Camera实例,ID指的是摄像头ID
}
catch(Exceptione){
//摄像头不可用(正被占用或不存在)
}
returnc;//不可用则返回null
}
注意,每次使用Cameraopen()时都要检查异常,如果摄像头被占用或者不存在的话,未检查异常将会导致应用程序被系统强行关闭。
(2)调用Camera的getParameters()方法获取拍照参数,该方法返回一个Camera.Parameters对象;
调用Camera.Parameters对象方法设置拍照参数;可用Camera.getCameraInfo()来确定摄像头朝前还是朝后以及图像的方向。
(3)调用Camera的takePciture()方法进行拍照。
(4)结束程序时,调用release()来释放资源。
camera=Camera.open
(1);//打开前置摄像头
//设置图片格式
if(camera!
=null)
{
try{
//设置摄像头参数
Camera.Parametersparameters=camera.getParameters();
//设置图片格式
parameters.setPictureFormat(ImageFormat.JPEG);
//设置图片质量
parameters.set("jpeg-quality",100);
}catch(Exceptione){
e.printStackTrace();//TODO:
handleexception
}
}
二、图片自由裁剪
关键代码如下:
publicvoidimageCut(Uriuri){
Intentintent=newIntent("com.android.camera.action.CROP");
intent.setDataAndType(uri,"image/*");
//开启裁剪功能
intent.putExtra("crop","true");
//设定宽高的比例
intent.putExtra("aspectX",1);
intent.putExtra("aspectY",1);
//设定裁剪图片宽高
intent.putExtra("outputX",100);
intent.putExtra("outputY",100);
//要求返回数据
intent.putExtra("return-data",true);
startActivityForResult(intent,100);
}
返回数据后直接在onActivityResult里对返回的图片数据进行显示就行了,这里由于剪切后的图片较小,个人觉得应该不用考虑OOM的问题,问题是,在调用自带的裁剪功能的时候,由于没看源码,所以不知道在调整裁剪框的时候,显示的那副图片有没有进行压缩,如果没有进行压缩,那么当图片很大的时候,加载起来就很容易出现OOM了,明显对此由于是调用官方的API,我没有方法去解决它。
唯一的办法就是不用它,而是自己去写一个,就可以避免这个问题。
利用如下的代码进行压缩,很好地避免OOM问题。
/*
*压缩图片,返回的是压缩后的照片
*/
publicstaticBitmaprevitionImage(Stringpath,intsize){
Bitmapbitmap=null;
try{
//先用图片路径打开图片文件,缓冲到一个缓存输入流中
BufferedInputStreamin=newBufferedInputStream(newFileInputStream(
newFile(path)));
//用参数代表变量来记录当前照片的信息,比如图片大小
BitmapFactory.Optionsoptions=newBitmapFactory.Options();
//把inJustDecodeBounds设置为true,则完全不用分配内存就可以得到给位图文件bitmap的信息,
//如此得到大小后,就可以对其进行7压缩,然后在内存中生成一个更小的bitmap,节省了内存
options.inJustDecodeBounds=true;
//译码位图文件,只为了得到原图的信息
BitmapFactory.decodeStream(in
null,options);
//记得关闭流
in.close();
inti=0;
while(true){
//右移i位是因为下面的pow取一半了,新生成的图片是原来的二分之一
if(((options.outWidth>>i)<=size)&&((options.outHeight>>i)<=size)){
//这时候应取得照片了
in=newBufferedInputStream(newFileInputStream(newFile(path)));
//pow是次方方法,2的i次方,inSampleSize图片均分取样值,例如
//inSampleSize==4returnsanimagethatis1/4thewidth/heightoftheoriginal,and1/16thenumberofpixels.
options.inSampleSize=(int)Math.pow(2.0,i);
//这时候的图片已经符合我们设定的256大小了,所以要在设置false,允许输出,创建图片
//真正地生成一个有像素的,经过缩放的bitmap
options.inJustDecodeBounds=false;
bitmap=BitmapFactory.decodeStream(in,null,options);//获得n分之一原图,小于256*256
break;
}else{
i++;
}
}
}catch(IOExceptione){
Log.i(TAG,"压缩图片出错"+e.toString());
}
returnbitmap;
}