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

[复制链接]

 
电梯直达

楼主

 
 发表于 2013-3-13 19:51:43 | 只看该作者 |只看大图 
本帖最后由 happy小妖同学 于 2013-4-19 18:02 编辑

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

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

[java] view plaincopy

  • 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.拍照时,将拍得的照片先保存在本地,通过修改之前的代码如下:

[java] view plaincopy

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

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

[java] view plaincopy

  • @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.打开相册选取图片

[java] view plaincopy

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

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

[java] view plaincopy

  • @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;
  • }
  • }
  • }

补充,这个附件是所有要用到的我都封装好了。直接拷到项目里面就OK了。Activity就用网上随便的一个都行,就没有单独写个demo出来了。

<ignore_js_op style="-ms-word-wrap: break-word;">

该贴已经同步到 happy小妖同学的微博

<ignore_js_op style="-ms-word-wrap: break-word;">

myzxing.zip

314.17 KB, 下载次数: 150, 下载积分: 下载豆 -2

Android相机、相册获取图片显示并保存到SD卡的更多相关文章

  1. Android开发调试日志工具类[支持保存到SD卡]

    直接上代码: package com.example.callstatus; import java.io.File; import java.io.FileWriter; import java.i ...

  2. Android自定义照相机实现(拍照、保存到SD卡,利用Bundle在Acitivity交换数据)

    Android自定义照相机实现 近期小巫在学校有一个创新项目,也不是最近,是一个拖了很久的项目,之前一直没有去搞,最近因为要中期检查,搞得我跟小组成员一阵忙活,其实开发一款照相机软件并不太难,下面就是 ...

  3. Android—将Bitmap图片保存到SD卡目录下或者指定目录

    直接上代码就不废话啦 一:保存到SD卡下 File file = new File(Environment.getExternalStorageDirectory(), System.currentT ...

  4. [置顶] Android学习系列-把文件保存到SD卡上面(6)

    Android学习系列-把文件保存到SD卡上面(5) 一般多媒体文件,大文件需要保存到SD卡中.关键点如下: 1,SD卡保存目录:mnt/sdcard,一般采用Environment.getExter ...

  5. Android 将文件保存到SD卡,从卡中取文件,及删除文件

    //保存到SD卡 private static String sdState = Environment.getExternalStorageState();     private static S ...

  6. Libgdx实现异步加载网络图片并保存到SD卡或者data/data目录下边

    Libgdx实现异步加载网络图片并保存到SD卡或者data/data目录下边,当本地有图片的时候,直接从本地读取图片,如果本地没有图片,将从服务器异步加载图片 package com.example. ...

  7. Linux笔记(开机自动将kerne log保存到SD卡中)

    有时候为了测试机器的稳定性,需要煲机测试几天的情况,这个时候机器已经封装好,不能再接串口线出来. 为了追溯问题,就需要将log信息保存下来. 于是就需要这样一个功能:系统启动后,自动将kernel的l ...

  8. Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅

      Android 高手进阶(21)  版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明出处http://blog.csdn.net/xiaanming/article/details ...

  9. Android 将文件保存到SD卡中

    ①写文件到sd卡中需要获得权限,在AndroidManifest.xml中添加如下权限: <uses-permission android:name="android.permissi ...

随机推荐

  1. Android开发的那些坑和小技巧

    1.android:clipToPadding 意思是控件的绘制区域是否在padding里面.默认为true.如果你设置了此属性值为false,就能实现一个在布局上事半功陪的效果.先看一个效果图. 上 ...

  2. Bootstrap系列 -- 28. 下拉菜单状态

    下拉菜单项的默认的状态(不用设置)有悬浮状态(:hover)和焦点状态(:focus). 下拉菜单项除了上面两种状态,还有当前状态(.active)和禁用状态(.disabled).这两种状态使用方法 ...

  3. ModernUI教程:第一个ModernUI应用(采用项目模板)

    在我们开始之前,请确保你已经为你的Visual2012或者2013安装了ModernUI for WPF的模板扩展: >>从Visual Studio 库 下载并安装VSIX扩展 > ...

  4. (旧)子数涵数·PS——冷色调与LOMO

    一.准备素材(我是从百度图库里下载的) 二.打开PS和素材 三.复制图层,快捷键Ctrl+J,并把原图层隐藏,只在副本上编辑(好习惯) 四.使用"匹配颜色"命令,增加"明 ...

  5. css的垂直居中

    请先看博客:http://www.jb51.net/css/39629.html

  6. 第二十二课:js事件原理以及addEvent.js的详解

    再看这篇博客之前,希望你已经对js高级程序编程一书中的事件模块进行了详读,不然我只能呵呵了. document.createEventObject,在IE下创建事件对象event. elem.fire ...

  7. iOS开发之格式化日期时间(转)

    在开发iOS程序时,有时候需要将时间格式调整成自己希望的格式,这个时候我们可以用NSDateFormatter类来处理.例如: //实例化一个NSDateFormatter对象 NSDateForma ...

  8. 关于软工项目beta版本

    项目总结 项目成员: 黄丰润 031302307 王旭銮 031302320 张家俊 031302329 张晓燕 031302343 项目完成度:实现了专业信息填写.查看,教师信息填写,报课和查看课表 ...

  9. .net架构设计读书笔记--第三章 第10节 命令职责分离(CQRS)简介(Introducing CQRS)

    一.分离查询命令 Separating commands from queries     早期的面向DDD设计方法的难点是如何设计一个类,这个类要包含域的方方面面.通常来说,任务软件系统方法调用可以 ...

  10. POJ-2777Count Color 线段树+位移

    这道题对于我这样的初学者还是有点难度的不过2遍A了还是很开心,下面说说想法-- Count Color Time Limit: 1000MS Memory Limit: 65536K Total Su ...