http://pan.baidu.com/s/1gd8lFKv 提取密码rqfd
最后来个Demo界面效果:(丑的不能再丑,大家还是忘了颜值看内在吧,哈哈)
来个引言唠叨一下,哈哈:Android开发经常需要对图片进行处理,如果处理不好,容易引发OOM(Out Of Memory,令人后背冒冷汗的内存溢出)。
在上传图片到服务器的时候,原图通常是需要进行一定压缩后才上传上去的.
为啥?
1.节省用户流量,如今流量这么贵,上传要流量,再次从服务器异步加载这张图片也要流量的啊
2.这么大的图在服务器里面占用磁盘空间的啊
3.在手机屏幕上面看一张8k分辨率的图有多大意义?如果能看出8k效果,那8k屏幕厂商可以哭瞎了
来来来,转入正题:所以本博客提供一个Demo,来挑战一下11张8k分辨率大图(603MB大小)进行连续压缩不OOM,并尽可能的高保真度。
如果大家的需求要求保真度再高一点,那么可以下载Demo后手动改里面的数值,达到自己想要的效果。
先说避免OOM的一些相关事项:
1.大图加载为bitmap时,无一例外的要对其进行图片处理:先只加载其宽高数据而不加载图片内容,然后对其进行图片缩放比例计算,得到一个合适的缩放比例,然后再利用这个比例,加载真正的图片内容,代码上面体现就是:
BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true; //仅加载图片宽高数据,而不加载实际图片内容 BitmapFactory.decodeFile(oldPath, opts); opts.inSampleSize = computeSampleSize(opts, -1, 960 * 960);//对图片进行缩放比例计算,取得一个合适的缩放比例 opts.inJustDecodeBounds = false;//可以开始加载图片实际内容了 bitmap = BitmapFactory.decodeFile(oldPath, opts); //利用缩放比例进行图片内容加载经过上面代码的处理,实际加载到内存中的图片大小并不会是图片文件大小所占用的大小,而是经过一定缩放后的大小。
2.如果经过上面步骤后,对图片的文件大小还是不满意,那么可以继续进行图片文件大小压缩
图片文件大小压缩利用的方法是:bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//其中options即为压缩的质量,baos为图片的字节数组输出流
看代码:
ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 100不压缩; int options = 90;//压缩为90% bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);// 质量压缩方法,这里options表示压缩,把数据存放到baos中 while (baos.toByteArray().length / 1024 > 200) { // 循环判断如果压缩后图片是否大于200kb,大于继续压缩 baos.reset();// 重置baos即清空baos options -= 10;// 每次都减少10 bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中 } FileOutputStream fOut = new FileOutputStream(file); fOut.write(baos.toByteArray()); fOut.flush();
3.还有关于OOM的一点是,打开的流记得关闭、置空,不再使用的临时bitmap,记得回收、置空。
最后有Demo链接可以进行下载测试,如果要能够正常运行demo,需要事先在SD卡下面的相关目录放置一些大图片,然后对照或者修改一下Demo代码中的文件,让代码中的文件名称及其路径与你放入SD卡中的文件名称及其路径匹配。
因为这个Demo是我在一个项目中应用的,当时也是找了很多资料,然后整合出来的这么一个Demo,现把它共享出来。
好了,其他代码一大段一大段的理论分析就不上了,直接上代码Demo。
http://download.csdn.net/detail/junjun071308/9123031