系统相机调用分析.docx
- 文档编号:3509748
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:25
- 大小:26.02KB
系统相机调用分析.docx
《系统相机调用分析.docx》由会员分享,可在线阅读,更多相关《系统相机调用分析.docx(25页珍藏版)》请在冰豆网上搜索。
系统相机调用分析
android手机有自带的照相机和图库,我们做的项目中有时用到上传图片到服务器,今天做了一个项目用到这个功能,所以把我的代码记录下来和大家分享,第一次写博客希望各位大神多多批评。
首先上一段调用android相册和相机的代码:
代码如下:
Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE);//调用android自带的照相机
photoUri=MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
startActivityForResult(intent,1);
代码如下:
Intenti=newIntent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);//调用android的图库
startActivityForResult(i,2);
代码如下:
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
//完成照相后回调用此方法
super.onActivityResult(requestCode,resultCode,data);
case1:
switch(resultCode){
caseActivity.RESULT_OK:
//照相完成点击确定
StringsdStatus=Environment.getExternalStorageState();
if(!
sdStatus.equals(Environment.MEDIA_MOUNTED)){//检测sd是否可用
Log.v("TestFile","SDcardisnotavaiable/writeablerightnow.");
return;}
Bundlebundle=data.getExtras();
Bitmapbitmap=(Bitmap)bundle.get("data");//获取相机返回的数据,并转换为Bitmap图片格式
FileOutputStreamb=null;
Filefile=newFile("/sdcard/pk4fun/");
file.mkdirs();//创建文件夹,名称为pk4fun//照片的命名,目标文件夹下,以当前时间数字串为名称,即可确保每张照片名称不相同。
网上流传的其他Demo这里的照片名称都写死了,则会发生无论拍照多少张,后一张总会把前一张照片覆盖。
细心的同学还可以设置这个字符串,比如加上“IMG”字样等;然后就会发现sd卡中myimage这个文件夹下,会保存刚刚调用相机拍出来的照片,照片名称不会重复。
Stringstr=null;
Datedate=null;
SimpleDateFormatformat=newSimpleDateFormat("yyyyMMddHHmmss");//获取当前时间,进一步转化为字符串
date=newDate(resultCode);
str=format.format(date);
StringfileName="/sdcard/myImage/"+str+".jpg";
sendBroadcast(fileName);
try{
b=newFileOutputStream(fileName);
press(Bitmap.CompressFormat.JPEG,100,b);//把数据写入文件
}catch(FileNotFoundExceptione){
e.printStackTrace();
}finally{
try{
b.flush();
b.close();
}catch(IOExceptione){
e.printStackTrace();
}
}break;
caseActivity.RESULT_CANCELED:
//取消
break;
}
break;
case2:
switch(resultCode){
caseActivity.RESULT_OK:
{
Uriuri=data.getData();
Cursorcursor=mActivity.getContentResolver().query(uri,null,
null,null,null);
cursor.moveToFirst();
StringimgNo=cursor.getString(0);//图片编号
StringimgPath=cursor.getString
(1);//图片文件路径
StringimgSize=cursor.getString
(2);//图片大小
StringimgName=cursor.getString(3);//图片文件名
cursor.close();
//Optionsoptions=newBitmapFactory.Options();
//options.inJustDecodeBounds=false;
//options.inSampleSize=10;
//Bitmapbitmap=BitmapFactory.decodeFile(imgPath,options);
}
break;
caseActivity.RESULT_CANCELED:
//取消
break;
}
break;
}
最后记得加权限
name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> name="android.permission.WRITE_EXTERNAL_STORAGE"/> name="android.permission.CAMERA"/> name="android.permission.RECORD_AUDIO"/> name="android.permission.WRITE_EXTERNAL_STORAGE"/> Android调用系统相机和自定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理(避免OOM),还有简要提一下有些人SurfaceView出现黑屏的原因。 Android应用拍照的两种方式,下面为两种形式的Demo展示出来的效果。 知识点: 一、调用系统自带的相机应用 二、自定义我们自己的拍照界面 三、关于计算机解析图片原理(如何正确加载图片到Android应用中) 所需权限: ? 1 2 3 4 5 6 name="android.permission.CAMERA"/> name="android.hardware.camera"/> name="android.hardware.camera.autofocus"/> name="android.permission.WRITE_EXTERNAL_STORAGE"/> 一、调用系统照相机程序拍照(方式一) 1.定义所需要的权限 2.我们需要定义调用系统相机App的Intent,当然是通过设定IntentFilter中的Action来打开我们想要的activity了。 MediaStore.ACTION_IMAGE_CAPTURE-这个Action将打开拍照的系统相机。 返回一个Image MediaStore.ACTION_VIDEO_CAPTURE-这个Action将打开录像的系统相机。 返回一个Video 在MediaStore.ACTION_IMAGE_CAPTURE中,我们可以看到这段话: 【ThecallermaypassanextraEXTRA_OUTPUTtocontrolwherethisimagewillbe written.IftheEXTRA_OUTPUTisnotpresent,thenasmallsizedimageisreturned asaBitmapobjectintheextrafield.Thisisusefulforapplicationsthatonly needasmallimage.IftheEXTRA_OUTPUTispresent,thenthefull-sizedimagewill bewrittentotheUrivalueofEXTRA_OUTPUT.】 3.API规定我们传入拍照得到图片的存储位置的Uri。 否则Bimmap将以一个压缩后的形式返回到我们当前Activity. intent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri);//settheimagefilename 则会把拍照的图片存储到我们传入的Uri对应的File里面。 4.我们调用startActivityForResult(intent)来启动这样一个系统相机app之后,然后在当前应用Activity的onActivityResult()中接受到返回拍照成功或者失败的消息,做相应处理。 5.“压缩处理”(Android应用中加载大图片),并显示到ImageView中。 二、自定义照相机 1.检查相机是否存在,并获取相机Camera。 2.创建一个相机图像预览类: extendsSurfaceView并implementsSurfaceHolder(我定义: MySurfaceView) 3.把这个预览类放入一个自定义布局layout里面,并且可以在layout里添加自己的其他按钮 4.设置对应的拍照按钮然后听事件 5.捕获照片和保存图片 6.释放掉我们使用的相机Camera,不然之后其他应用将无法使用它。 三、计算机解析图片的方式和Android中大图片Bitmap的压缩显示处理 这个问题有点老生长谈了,平时我们经常遇到一些图片资源,我们把它加载到内存发现抛出内存不够用的异常,即OOM,当然加载图片时出现的OOM情况有很多种,比如单张图片没有做压缩,导致图片占用内存过大而发生内存溢出,也有多张图片一次性加载进来,导致的内存溢出。 通常单张大图,我们加载进来往往会经过一个图片的压缩处理的过程,而如果多张图片加载,我们可能就需要一些缓存机制,再加上一些算法来保证程序不出现OOM。 我们这里想要讲的知识点跟单张大图比较有关系 首先,我们知道一个图片,它是由很多像素点来表示的,而像素点的个数只跟图片的分辨率有关,而跟图片所占的内存空间大小无关。 比如我们的桌面壁纸: 1280*768的分辨率,那么它就有1280*768=983040个像素点,这意味着什么呢? 我们知道我们要表示一个像素点的颜色,最经常我们需要RGB三种颜色来表示,而R: 0~255,相当于两个FF的位置,就是8位,这样的话RGB合起来,一个像素点的表示就需要24位(这就是我们平衡听到的24位图),而加上透明度的8位,就是平时说的32位图。 那么一张图片,它加载到内存中的话,它会占用多大的空间呢? 计算方法: (像素点*一个像素所占用的byte数)/1024/1024(MB) 以1280*768的分辨率,32位图为例: 所占内存大小: ((1280*768*(32/8))/1024)/1024=3.75(MB) 说了这么多,那么我们再来说下Android系统的规定吧,Android系统严格规定了每个应用所能分配的最大的内存为多少,我们知道有一个VM值(在我们创建模拟器的时候),这个VM值里面便是我们所说的堆空间(HeapSize),当你的应用占用的空间已经超出我们定义的堆空间大小,那么不好意思,OOM 这样的话,我们明白了图片的大小占据原理,还有尽量不要超出这个堆空间,那么OK,现在问题变得简单了。 如果我们有一种方式可以在图片加载进来之前,知道图片的大小,然后改变它的长、宽,这样的话,分辨率便变小了,这样出来的乘积也就变小了。 比如: 我们的屏幕只有320*240,这时候你加载大分辨的图片进来最多也只能显示成这样,所以我们常采用的是对图片进行压缩处理。 这里有个概念叫压缩比: 长: 1024/320=3.2 约等于3 宽: 768/240=3.2 那这样我们如果把图片压缩成这样大小的,最后的图片加载进来的大小便是 ((320 *240 *(32/8))/1024)/1024=0.29(MB) 希望我这样讲完,大家都能听懂了,我这里先把照相机实例中出现的关于如果处理这块图片的代码先粘出来 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 //-----------------------Android大图的处理方式--------------------------- privatevoidsetPicToImageView(ImageViewimageView,FileimageFile){ intimageViewWidth=imageView.getWidth(); intimageViewHeight=imageView.getHeight(); BitmapFactory.Optionsopts= newOptions(); //设置这个,只得到Bitmap的属性信息放入opts,而不把Bitmap加载到内存中 opts.inJustDecodeBounds= true; BitmapFactory.decodeFile(imageFile.getPath(),opts); intbitmapWidth=opts.outWidth; intbitmapHeight=opts.outHeight; //取最大的比例,保证整个图片的长或者宽必定在该屏幕中可以显示得下 intscale=Math.max(imageViewWidth/bitmapWidth,imageViewHeight/bitmapHeight); //缩放的比例 opts.inSampleSize=scale; //内存不足时可被回收 opts.inPurgeable= true; //设置为false,表示不仅Bitmap的属性,也要加载bitmap opts.inJustDecodeBounds= false; Bitmapbitmap=BitmapFactory.decodeFile(imageFile.getPath(),opts); imageView.setImageBitmap(bitmap); } 关于堆空间: 堆(HEAP)是VM中占用内存最多的部分,通常是动态分配的。 堆的大小不是一成不变的,通常有一个分配机制来控制它的大小。 比如初始的HEAP是4M大,当4M的空间被占用超过75%的时候,重新分配堆为8M大;当8M被占用超过75%,分配堆为16M大。 倒过来,当16M的堆利用不足30%的时候,缩减它的大小为8M大。 重新设置堆的大小,尤其是压缩,一般会涉及到内存的拷贝,所以变更堆的大小对效率有不良影响。 废话少说下面就看代码咯~~为了大家看起来方便点,代码的结构可能不是很规范! 源码下载地址: 代码部分: 一、用系统的相机 按钮点击之后开启系统相机Activity ? 1 2 3 4 5 6 7 8 9 10 11 findViewById(R.id.system_camera_btn).setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent= newIntent(); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); imageFileUri=getOutFileUri(TYPE_FILE_IMAGE);//得到一个FileUri intent.putExtra(MediaStore.EXTRA_OUTPUT,imageFileUri); startActivityForResult(intent,SYSTEM_CAMERA_REQUESTCODE); } }); 生成File文件,并得到Uri ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 //-----------------------生成Uri--------------------------------------- //得到输出文件的URI privateUrigetOutFileUri(intfileType){ returnUri.fromFile(getOutFile(fileType)); } //生成输出文件 privateFilegetOutFile(intfileType){ StringstorageState=Environment.getExternalStorageState(); if(Environment.MEDIA_REMOVED.equals(storageState)){ Toast.makeText(getApplicationContext(), "oh,no,SD卡不存在",Toast.LENGTH_SHORT).show(); returnnull; } FilemediaStorageDir= newFile(Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) ,"MyPictures"); if(! mediaStorageDir.exists()){ if(! mediaStorageDir.mkdirs()){ Log.i("MyPictures", "创建图片存储路径目录失败"); Log.i("MyPictures", "mediaStorageDir: "+mediaStorageDir.getPath()); returnnull; } } Filefile= newFile(getFilePath(mediaStorageDir,fileType)); returnfile; } //生成输出文件路径 privateStringgetFilePath(FilemediaStorageDir, intfileType){ StringtimeStamp=newSimpleDateFormat("yyyyMMdd_HHmmss") .format(newDate()); StringfilePath=mediaStorageDir.getPath()+File.separator; if(fileType==TYPE_FILE_IMAGE){ filePath+=("IMG_"+timeStamp+ ".jpg"); }elseif(fileType==TYPE_FILE_VEDIO){ filePath+=("VIDEO_"+timeStamp+ ".mp4"); }else{ returnnull; } returnfilePath; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 系统 相机 调用 分析