1、android中计算图片占用堆内存的kB大小跟图片本身的kB大小无关,而是根据图片的尺寸来计算的。

比如一张 480*320大小的图片占用的堆内存大小为:

480*320*4/1024=600kB  之所以要乘以4,是因为在android中使用的ARGB图片,图片一个像素占用四个字节。

2、手机出厂时 堆内存(Heap)是固定的,所以为了不造成OOM,我们就需要生成bitmap时对图片进行压缩处理。

实际使用中我们压缩图片的标准是手机屏幕大小作为参照的,这个主要是因为,即便是图片尺寸跟屏幕尺寸相同,换算出来所占的内存大小也要远小于手机堆存。

为了讲解方便,我们就以 480*320大小的手机为例,图片压缩为同手机屏幕同尺寸时,所占的大小为 600kb,也就是0.6M,而480*320的手机的出厂heap一般是16M,这个数字根据每个厂商有所差异。

3、压缩方式:通过bitmap的options

首先大家要知道,当图片太大造成加载时,报OOM异常是在哪个地方报的?

打印测试知道是在:Bitmap bitmap =  BitmapFactory.decodeFile(url)这行就报错。所以我们的处理如下:

/**
* 压缩图片
*
* @param photoPath
*/
public static Bitmap compressImage(Activity act, String photoPath) {
int screenWidth = act.getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = act.getWindowManager().getDefaultDisplay().getHeight();
LogUtils.logInfoStar("screenWidth为" + screenWidth + "------screenHeight" + screenHeight);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;//设置为true的目的,拿到图片的一些附属信息
BitmapFactory.decodeFile(photoPath, opts);
int imgWidth = opts.outWidth;
int imgHeight = opts.outHeight;
//获取屏幕尺寸的方式二:支持13以上版本,就是使用point存储宽高,然后再取出来。
// Point point=new Point();
// getWindowManager().getDefaultDisplay().getSize(point);
// screenWidth=point.x; 8 // screenHeight=point.y;
LogUtils.logInfoStar("图片原大小" + "imgWidth为:" + imgWidth + "imgHeight" + imgHeight);
//按屏幕大小获取的压缩比例,加入判断,只有图片尺寸大于屏幕尺寸时才压缩
if (imgHeight > screenHeight || imgWidth > screenWidth) {
int sizeByScreenSize = imgWidth / screenWidth > imgHeight / screenHeight ? imgWidth / screenWidth : imgHeight / screenHeight;
//再在此基础把压缩比例增大10倍
opts.inSampleSize = sizeByScreenSize * 10;
LogUtils.logInfoStar("inSampleSize" + sizeByScreenSize);
} else {
opts.inSampleSize = 1;
}
opts.inJustDecodeBounds = false;
Bitmap mImage = BitmapFactory.decodeFile(photoPath, opts);
return mImage;
}

总结:

##缩放加载大图片
1.获取你想显示的图片应该有的大小,如果是全屏,就获取屏幕大小

2.获取图片的原始大小,不将图片真正加载到内存,只拿到图片的附属信息
Options opts = new Options();
设置为true,不加在内存,只拿信息
opts.inJustDecodeBounds = true;
3.对图片做压缩处理,压缩的前提是图片的大小大于你要显示的区域大小
按照宽或者高的比例进行计算,选择比例大的那个进行压缩
压缩的比例值最后复制给
opts.inSampleSize = scale;
4.比例设置完之后,这时候才是真正的去加载图片到内存当中
opts.inJustDecodeBounds = false;
5.最后一部才是加载图片
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", opts);

我们做这么多操作的最终目的其实就是为了要opts.inSampleSize = scale这个值。

Android中的图片压缩的更多相关文章

  1. Android笔记(七十五) Android中的图片压缩

    这几天在做图记的时候遇第一次遇到了OOM,好激动~~ 追究原因,是因为在ListView中加载的图片太大造成的,因为我使用的都是手机相机直接拍摄的照片,图片都比较大,所以在加载的时候会出现内存溢出,那 ...

  2. Android 中对于图片的内存优化方法

    Android 中对于图片的内存优化方法,需要的朋友可以参考一下     1. 对图片本身进行操作 尽量不要使用 setImageBitmap.setImageResource. BitmapFact ...

  3. Android 简单介绍图片压缩和图片内存缓存

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9316683 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工, ...

  4. Android中获取图片的宽和高

    在Android中,我们想获取图片的宽和高应该怎么办?一.正常加载图片的方法下获取宽和高 举一个简单的例子:创建一个图片的副本 //加载原图 Bitmap bmSrc = BitmapFactory. ...

  5. Java乔晓松-android中获取图片的缩略图(解决OutOfMemoryError)内存溢出的Bug

    由于android获取图片过大是会出现内存溢出的Bug 07-02 05:10:13.792: E/AndroidRuntime(6016): java.lang.OutOfMemoryError 解 ...

  6. WEB前端开发中的图片压缩

    web前端开发中,图片的重要性不言而喻,而由于一些图片的大小加上现在国内的网速不给力等种种原因,我们非常有必要对网站使用的图片进行压缩,压缩图片必然会带来图片质量的损失,我们要尽可能的在质量降低很小的 ...

  7. 在Android中实现图片的裁剪

        本实例的功能是将用户选择的图片裁剪后放入ImagView,布局文件是个Button和ImageView.为了图片的正常显示,我们在裁剪后先将裁剪好的图片先存放到SD卡中,这样就能在以后开启应用 ...

  8. Android中9-Patch图片之理解

    在android中,不仅可以将扩展名为.png,.jpg,.gif的普通图片作为图片资源,而且可以将扩展名为.9.png的9-Patch图片作为图片资源.扩展名为.png,.jpg,.gif的普通图片 ...

  9. Android学习之图片压缩,压缩程度高且失真度小

    曾经在做手机上传图片的时候.直接获取相机拍摄的原图上传,原图大小一般1~2M.因此上传一张都比較浪费资源,有些场景还须要图片多张上传,所以近期查看了好多前辈写的关于图片处理的资料.然后试着改了一个图片 ...

随机推荐

  1. Uint8Array 对象

    8 位无符号整数值的类型化数组.内容将初始化为 0.如果无法分配请求数目的字节,则将引发异常. 语法 uint8Array = new Uint8Array( length ); uint8Array ...

  2. NSAttributedString

    1.    使用这个类,必须先导入CoreText框架. 2.    给UILabel设置attributedText了会导致给UILabel中text,font,textColor,shadowCo ...

  3. mysql高负载的问题排查

    http://dngood.blog.51cto.com/446195/1150031 log_slow_queries = /usr/local/mysql/var/slow_queries.log ...

  4. 统计哪些程序占用了swap

    命令如下 : for i in `cd /proc;ls |grep "^[0-9]"|awk ' $0 >100'` ;do awk '/Swap:/{a=a+$2}END ...

  5. 同一个主机上的JVM实例之间通信

    hadoop yarn里用了RPC调用.NM里面文件本地化类ContainerLocalizer用RPC心跳方式跟本机的ResourceLocalizationService通信. 用shared m ...

  6. PostgreSQL:安装

    官网地址:https://www.postgresql.org/ 安装文件下载地址:http://www.enterprisedb.com/products-services-training/pgd ...

  7. Greenplum:学习资料

    Greenplum技术浅析:http://www.cnblogs.com/end/archive/2012/08/17/2644290.html Greenplum 数据库架构分析:http://ww ...

  8. Swift实战-豆瓣电台(一)准备

    一 准备 我们现在看看我们要做一个什么样的东西 观看地址:http://v.youku.com/v_show/id_XNzI4ODY2Mjky.html 布局 通过上面这张图我们可以看出整个demo有 ...

  9. Redis分布式

    昨天公司技术大牛做了一个Redis分布式的技术分享: Redis分布式资源: http://redis.io/topics/cluster-tutorialhttp://redis.io/topics ...

  10. Struts2.3+Spring+iBatis 初学之问题判断

    小白接下来将会总结下我再学习Spring的学习过程中(ssi框架)中遇到的问题,以后会不断的进行更新. 最容易犯的问题,就是声明bean的时候,属性引用其他声明的bean的时候,name没有进行好对应 ...