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

原创 2013年03月09日 09:26:00

如题,这个需求本不是一个很复杂的过程,但是却存在一些隐患,我也是最近在项目中碰到这个问题,将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感兴趣的朋友可以加入我们的讨论QQ群,在这里,我们只讨论干货:

iOS群:220223507

Android群:282552849


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

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


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


版权声明:本文为博主原创文章,未经博主允许不得转载。

android 调用系统照相机拍照后保存到系统相册,在系统图库中能看到

android 调用系统照相机进行拍照,并且保存到系统相册,调用系统相册的时候能看到。...

Android拍照保存在系统相册

可能大家都知道我们保存相册到Android手机的时候,然后去打开系统图库找不到我们想要的那张图片,那是因为我们插入的图片还没有更新的缘故,先讲解下插入系统图库的方法吧,很简单,一句代码就能实现 Med...

Android 使用系统相机拍摄照片保存到本地并在系统相册中显示

这是我的第一篇博客文章,一直获取别人的劳动成果,今天开始我也要分享我的劳动成果给大家。这篇博客主要探讨使用Android 手机自带相机拍摄照片并把照片保存到本地,并通过广播通知系统相册进行更新图片,这...

android调用系统相机拍照保存照片并显示在当前界面

主要思路是在使用照相机拍照,然后为拍得的照片在SD卡新开一个储存照片的文件 代码:因为要调用照相机和SD卡所以需要添加以下权限: 在manifests中添加 android:name...
  • LLXLQY
  • LLXLQY
  • 2016年04月29日 12:08
  • 4942

Android 图片存储到指定路径和相册

我们在平常项目中,可能会存储一些头像,二维码之类的。这篇文章主要也是介绍自己在存储中会遇到的问题以及一些改进方案。1.首先是长按保存:这个可以去参照网络上的,无非是自己先要拼接好一个文件路径。注意:I...

android拍照后保存原图至指定文件夹

这个问题差不多捣鼓了一天,还是没整出来。 但是功夫不负有心人,各种百度,各种搜,还是把这坑货玩意儿倒腾出来了,废话不多讲,贴代码↓↓↓ String path = Environment....

Android相机拍照保存高清原图

代码不是很复杂我就直接上代码了 /** 拍照获取图片 */ public void photo() { try { Intent openCameraIntent = new Int...

拍照和从相册中选取照片,并保存到SD卡上

拍照和从相册中选取照片,并保存到SD卡上

Android 从手机相册获取图片 uri 路径 从相机获取照片

从手机相册获取图片Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_O...

Android 调用相机或从相册获取图片

拍照或者从相册获取图片的功能。 之前项目中有做过更换用户头像,拍照或者从相册获取,虽然没什么问题,功能也能实现,但是总感觉怪怪的。最近看了郭霖大神的地一行代码(第二版),受益良多,故将此功能分享给大...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android相机、相册获取图片显示并保存到SD卡
举报原因:
原因补充:

(最多只允许输入30个字)