`
v5browser
  • 浏览: 1130718 次
社区版块
存档分类
最新评论

Android相机、相册获取图片显示并保存到SD卡

 
阅读更多

如题,这个需求本不是一个很复杂的过程,但是却存在一些隐患,我也是最近在项目中碰到这个问题,将Android通过相机或相册获取图片并最终显示在界面上做了一个小研究,现将一些结果和附上的一个Demo叙述如下:

做过类似需求的同学都知道,在Activity中通过如下代码可以启动相机,然后在重写的onActivityResult方法中可以获取到返回的照片数据:

Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(openCameraIntent, TAKE_PICTURE);

问题来了,不知大家是否有发现,在onActivityResult方法里通过Intent的getData方法获取的数据转换成bitmap并显示在界面上,有时候会有取不到数据,或者显示的bitmap会非常小,如果将bitmap保存到sd卡后会发现,图片的分辨率很低,并且图片大小也是经过压缩的,不管将相机的像素设置多高,最后通过这种方式返回的bitmap总是经过压缩了的。如果想获得理想的照片大小和分辨率改如何处理呢?以下是我的处理方法,虽然不是最好,但是帮我解决了这个需求。我先来简述一下为什么返回的图片是经过了压缩的。

大家都知道,现在手机像素少则500W或800W,多则4KW(某亚),就拿常见的800W像素的相机拍出来的照片来说,分辨率大概在3200*2400左右,我的测试机型是LG optimus 2x,2.3.7的系统,用800W像素拍出来大概就是这个分辨率,照片大小在2M左右。试想一下,在Android系统中bitmap占用4个字节,3200*2400*4=?,结果大家自己算算,如果为了一张图片,耗用这么大的内存,肯定是不合理的,并且,官方文档中有说明,Android系统分配给每个应用的最大内存是16M,所以,系统为了防止应用内存占用过大,对于在应用内通过相机拍摄的图片最终返回来的结果进行了压缩,压缩后的图片变得很小,通过之前说的getData的方式只能满足比如显示个头像这样的需求,如果要显示大图,就会出现模糊的情况。那如何获取清晰的大图呢?我的解决思路如下:

1.拍照时,将拍得的照片先保存在本地,通过修改之前的代码如下:

Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"image.jpg"));
//指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换
openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

2.在onActivityResult方法中再将图片取出,并经过缩小处理再显示在界面上或上传给服务器(压缩比例自定义)

@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK) {
			switch (requestCode) {
			case TAKE_PICTURE:
				//将保存在本地的图片取出并缩小后显示在界面上
				Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/image.jpg");
				Bitmap newBitmap = ImageTools.zoomBitmap(bitmap, bitmap.getWidth() / SCALE, bitmap.getHeight() / SCALE);
				//由于Bitmap内存占用较大,这里需要回收内存,否则会报out of memory异常
				bitmap.recycle();
				
				//将处理过的图片显示在界面上,并保存到本地
				iv_image.setImageBitmap(newBitmap);
				ImageTools.savePhotoToSDCard(newBitmap, Environment.getExternalStorageDirectory().getAbsolutePath(), String.valueOf(System.currentTimeMillis()));
				break;
			default:
				break;
			}
		}
	}

由于Android给bitmap分配的内存最大不超过8M,所以对使用完的较大的Bitmap要释放内存,调用其recycle()方法即可。然后将缩小(缩小方法在Demo源码中有)后的bitmap显示在界面上或保存到SD卡,至于之前保存的原图,可以删掉,也可以放在那,下次拍照时,这张原图就会被下一张照片覆盖,所以SD卡上使用只有一张临时图片,占用也不是很大。


以上讲的是拍照获取图片,如果是从相册中获取图片又如何处理呢,我的方法如下:

1.打开相册选取图片

Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);
					openAlbumIntent.setType("image/*");
					startActivityForResult(openAlbumIntent, CHOOSE_PICTURE);

2.在onActivity方法中处理获取到的图片,思路和之前类似

@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK) {
			switch (requestCode) {
			case CHOOSE_PICTURE:
				ContentResolver resolver = getContentResolver();
				//照片的原始资源地址
				Uri originalUri = data.getData(); 
	            try {
	            	//使用ContentProvider通过URI获取原始图片
					Bitmap photo = MediaStore.Images.Media.getBitmap(resolver, originalUri);
					if (photo != null) {
						//为防止原始图片过大导致内存溢出,这里先缩小原图显示,然后释放原始Bitmap占用的内存
						Bitmap smallBitmap = ImageTools.zoomBitmap(photo, photo.getWidth() / SCALE, photo.getHeight() / SCALE);
						//释放原始图片占用的内存,防止out of memory异常发生
						photo.recycle();
						
						iv_image.setImageBitmap(smallBitmap);
					}
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}  
				break;
			
			default:
				break;
			}
		}
	}


运行截图(个人夏天靓照一张大笑):


这一篇就讲述了由一个需求所发现的一个问题,并结合我的解决方法,欢迎有更好方法的同学指出并相互交流!


Demo下载地址:点击下载


对Android&IOS感兴趣的朋友可以加入我们的讨论,在这里,我们只讨论干货:

iOS群:220223507

Android群:282552849


觉得文章对你有用,点击右下角的转发按钮分享给更多人!

同时欢迎关注我的新浪微博和我交流:@唐韧_Ryan


《Android拍照、相册选取、裁剪图片综合Demo》


分享到:
评论

相关推荐

    Android相机、相册获取图片显示和保存

    demo为仿微信朋友圈发动态的功能,实现从相机拍照和相册(相册为自己实现且支持同时选取多张图片)选取图片显示和删除并保存到本地SD卡操作(保存到本地的是高清的压缩图片小于100KB 分辨率1280*720 可以直接上传到...

    Android相机、相册获取图片显示并保存

    实现从相机拍照和相册选取图片显示并保存到本地SD卡操作Demo,避免了Bitmap导致的内存溢出

    Android 相机相册权限设置方法

    今天小编就为大家分享一篇Android 相机相册权限设置,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

    Android项目源码获取照片裁剪图片压缩图片工具库.zip

    支持通过相机拍照获取图片 支持从相册选择图片 支持从文件选择图片 支持批量图片选取 支持图片压缩以及批量图片压缩 支持图片裁切以及批量图片裁切 支持照片旋转角度自动纠正 支持自动权限管理(无需关心SD卡...

    Android打开手机相册获取图片路径

    本文实例为大家分享了Android打开手机相册获取图片路径的具体代码,供大家参考,具体内容如下 根据打开相机返回的Uri uri = data.getData();获取该相片的真正SD卡路径! 权限 <uses android:name=android....

    安卓拍照或从相册、文件中选择开源库.zip

    支持通过相机拍照获取图片 支持从相册选择图片 支持从文件选择图片 支持批量图片选取 支持图片压缩以及批量图片压缩 支持图片裁切以及批量图片裁切 支持照片旋转角度自动纠正 支持自动权限管理(无需关心SD卡及摄像头...

    Android相机拍照、截图功能的实例演示

     将保存在本地的图片取出并缩小后显示在界面上、由于Bitmap内存占用较大,这里需要回收内存,否则会报out of memory异常、将处理过的图片显示在界面上,并保存到本地、使用ContentProvider通过URI获取原始图片、为...

    Android实现调用系统图库与相机设置头像并保存在本地及服务器

    * 1、实现原理:用户打开相册或相机选择相片后,相片经过压缩并设置在控件上,图片在本地sd卡存一份(如果有的话,没有则内部存储,所以还 * 需要判断用户是否挂载了sd卡),然后在服务器上存储一份该图片,当下次再次启动...

    安卓调用手机相机压缩并上传图片

    搜集网上资源做的,对手机保存原来的图片保存后,对原图压缩并保存。并删除原图。在图片上传完成后,对压缩的图片进行删除。减少SD卡的内存空间。

    android中打开相机、打开相册进行图片的获取示例

    这里介绍在Android中实现相机调取、拍照片、获取照片、存储新路径等已经打开相册、选择照片等功能 首先看一下界面,很简单 配置读取内存卡和调用照相头的功能 <!-- 使用网络权限 --> <uses android:name...

    Google Android SDK开发范例大全(第3版) 1/5

    3.26 指定安装应用程序迁移至SD卡 3.27 手机动态Layout主题随手势物换迁移 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞 4.2 设计具有背景图的按钮 4.3 给圣诞老人的信息 4.4 我同意条款 4.5 消费券采购...

    《Google Android SDK开发范例大全(第3版)》.pdf

    3.26 指定安装应用程序迁移至sd卡 78 3.27 手机动态layout主题随手势物换迁移 79 第4章 史上超豪华的手机控件 84 4.1 edittext与textview共舞 85 4.2 设计具有背景图的按钮 86 4.3 给圣诞老人的信息...

    android图像绘制(六)获取本地图片或拍照图片等图片资源

    从SD卡中获取图片资源,或者拍一张新的图片。 先贴代码 获取图片: 注释:拍照获取的话,可以指定图片的保存地址,在此不说明。 代码如下: CharSequence[] items = {“相册”, “相机”}; new AlertDialog.Builder...

    Google Android SDK开发范例大全(第3版) 4/5

    3.26 指定安装应用程序迁移至SD卡 3.27 手机动态Layout主题随手势物换迁移 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞 4.2 设计具有背景图的按钮 4.3 给圣诞老人的信息 4.4 我同意条款 4.5 消费券采购...

    Google Android SDK开发范例大全(第3版) 3/5

    3.26 指定安装应用程序迁移至SD卡 3.27 手机动态Layout主题随手势物换迁移 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞 4.2 设计具有背景图的按钮 4.3 给圣诞老人的信息 4.4 我同意条款 4.5 消费券采购...

    Google Android SDK开发范例大全(第3版) 5/5

    3.26 指定安装应用程序迁移至SD卡 3.27 手机动态Layout主题随手势物换迁移 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞 4.2 设计具有背景图的按钮 4.3 给圣诞老人的信息 4.4 我同意条款 4.5 消费券采购...

    Google Android SDK开发范例大全(第3版)part2

     3.26 指定安装应用程序迁移至SD卡  3.27 手机动态Layout主题随手势物换迁移  第4章 史上超豪华的手机控件  4.1 EditText与TextView共舞  4.2 设计具有背景图的按钮  4.3 给圣诞老人的信息  4.4 我同意...

Global site tag (gtag.js) - Google Analytics