Android之bitmap压缩的几种方法的解读

转载:http://blog.csdn.net/chzphoenix/article/details/30242315?utm_source=tuicool&utm_medium=referral

最近在研究微信的sdk,在缩略图这遇到了一点问题。

微信的缩略图要求是不大于32k,这就需要对我的图片进行压缩。试了几种方法,一一道来。



1、质量压缩法:

代码如下

ByteArrayOutputStream baos = new ByteArrayOutputStream();  image.compress(Bitmap.CompressFormat.JPEG, 100, baos);int options = 100;  while ( baos.toByteArray().length / 1024>32) {  baos.reset();image.compress(Bitmap.CompressFormat.JPEG, options, baos);options -= 10;}  ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);

最开始使用这个来进行压缩,但是始终压缩不到32k这么小。后来看高手的解释才明白,这种压缩方法之所以称之为质量压缩,是因为它不会减少图片的像素。它是在保持像素的前提下改变图片的位深及透明度等,来达到压缩图片的目的。进过它压缩的图片文件大小会有改变,但是导入成bitmap后占得内存是不变的。因为要保持像素不变,所以它就无法无限压缩,到达一个值之后就不会继续变小了。显然这个方法并不适用与缩略图,其实也不适用于想通过压缩图片减少内存的适用,仅仅适用于想在保证图片质量的同时减少文件大小的情况而已。

2、采样率压缩法:

代码如下

            ByteArrayOutputStream out = new ByteArrayOutputStream();image.compress(Bitmap.CompressFormat.JPEG, 100, out);BitmapFactory.Options newOpts = new BitmapFactory.Options();  int be = 2;newOpts.inSampleSize = be; ByteArrayInputStream isBm = new ByteArrayInputStream(out.toByteArray());  Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);

第二个使用的是这个方法,可以将图片压缩到足够小,但是也有一些问题。因为采样率是整数,所以不能很好的保证图片的质量。如我们需要的是在2和3采样率之间,用2的话图片就大了一点,但是用3的话图片质量就会有很明显的下降。这样也无法完全满足我的需要。不过这个方法的好处是大大的缩小了内存的使用,在读存储器上的图片时,如果不需要高清的效果,可以先只读取图片的边,通过宽和高设定好取样率后再加载图片,这样就不会过多的占用内存。如下

 BitmapFactory.Options newOpts = new BitmapFactory.Options();   newOpts.inJustDecodeBounds = true;  Bitmap bitmap = BitmapFactory.decodeFile(path,newOpts);newOpts.inJustDecodeBounds = false;  int w = newOpts.outWidth;  int h = newOpts.outHeight;  //计算出取样率newOpts.inSampleSize = be;bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  

这样的好处是不会先将大图片读入内存,大大减少了内存的使用,也不必考虑将大图片读入内存后的释放事宜。



3、缩放法:

以上俩个方法都无法满足要求,只好考虑用缩放来实现。本不想用这种方法来实现,不过网上看到的方法基本都是上面俩种。缩放法其实很简单,设定好matrix,在createBitmap就可以了。但是我们并不知道缩放比例,而是要求了图片的最终大小。直接用大小的比例来做的话肯定是有问题的,用大小比例的开方来做会比较接近,但是还是有差距。但是只要再做一下微调应该就可以了,微调的话就是修改过的图片大小比最终大小还大的话,就进行0.8的压缩再比较,循环直到大小合适。这样就能得到合适大小的图片,而且也能比较保证质量。代码如下

    ByteArrayOutputStream out = new ByteArrayOutputStream();  image.compress(Bitmap.CompressFormat.JPEG, 85, out);  float zoom = (float)Math.sqrt(size * 1024 / (float)out.toByteArray().length);  Matrix matrix = new Matrix();  matrix.setScale(zoom, zoom);  Bitmap result = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true);  out.reset();  result.compress(Bitmap.CompressFormat.JPEG, 85, out);  while(out.toByteArray().length > size * 1024){  System.out.println(out.toByteArray().length);  matrix.setScale(0.9f, 0.9f);  result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true);  out.reset();  result.compress(Bitmap.CompressFormat.JPEG, 85, out);  }   

4、RGB_565法:

默认bitmap会使用ARGB_8888格式,转换成RGB_565会减少一半的内存开销,而且极大的保证了图片质量。

但是注意如果想保留图片透明度,如一些PNG图片,那么就不能使用此方法。

具体使用方法见http://blog.csdn.net/chzphoenix/article/details/42171653



感觉在bitmap压缩这块应该有更有效更方便的方法,可惜网上没有找到,自己对这方面的理解可能也不够。有更好的方法,或者文章有错误的地方,希望大家来指正。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/294021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何通过 C# kill 指定进程?

咨询区 robr我用代码动态的打开了一个 IE 进程,参考如下代码:static void Main(string[] args){ProcessStartInfo startInfo new ProcessStartInfo("iexplore.exe");startInfo.WindowStyle ProcessWindowStyle.Hidden;startInfo.Arguments …

[转]面向接口编程详解(一)——思想基础

我想,对于各位使用面向对象编程语言的程序员来说,“接口”这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,…

bootstrap模态框

bootsrtap模态框不可叠加使用,点击提交时需要确认,暂时未解决转载于:https://www.cnblogs.com/witchgogogo/p/5550338.html

Oracle 在 多个Virtualbox 虚拟机间 跨不同物理宿主机进行通信

因为单位网络管理的原因,不太方便使用 Virtualbox 的Bridge Adapter 模式,故此欲采用NAT模式,不对外不暴露虚拟机IP。 但是此时会有一个问题:采用NAT模式后,在通常情况下, 从外面看,或者从物理机…

Android之解决在非Activity中使用startActivity

今天遇到一个问题就是,如何在非activity里面使用startActivity(); 解决办法如下、 需要我们有context intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent);

亚马逊 html代码转换,亚马逊七种产品描述常用HTML代码,文字颜色代码让Listing更出彩...

排版风格和排版水平对于亚马逊Listing的运营至关重要。虽说亚马逊以产品为王,但如果消费者打开的是一篇毫无美感的排版,视觉体验不舒服,获取不到吸引他的卖点,转化率将大大降低!没使用HTML代码的卖家,产品描…

如何将自定义的 Delegate 转成 Func 委托?

咨询区 AndreyAkinshin场景是这样的&#xff0c;我自定义了一个 SomeDelegate 委托&#xff0c;然后将 Inc 方法灌入到其中&#xff0c;同时我也将 Inc 赋值给了 Func<int,int> 委托&#xff0c;参考代码如下&#xff1a;class Program{static void Main(string[] args){…

java 文件上传至oracle blob字段 实现

2019独角兽企业重金招聘Python工程师标准>>> 指定文件夹下的所有文件上传至oracle的blob字段&#xff0c;java实现 package com.huth;import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.FileInputStream; i…

基于DDD的.NET开发框架 - ABP工作单元(Unit of Work)

返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。 ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点&#xff0c;它旨在成为一个通用的WEB应用程序框架和项目模板。 ABP的官方网站&#xff1a;http://www.aspnetboilerp…

中国这门失传已久的武林绝学,竟让研究它的老外拿了诺贝尔奖

全世界只有3.14 % 的人关注了爆炸吧知识欲练神功学好物理中国武术&#xff0c;博大精深。能够掌握一门武林绝学&#xff0c;是全世界男人的终极梦想。可翻翻公认的武林十大绝学&#xff1a;葵花宝典、六脉神剑、九阳神功....不是断子绝孙&#xff0c;就是杀人于无形&#xff0c…

中国地区三级联动下拉菜单的实现

1.首先是js文件(area.js)&#xff1a; 1 function Dsy()2 {3 this.Items {};4 }5 Dsy.prototype.add function(id,iArray)6 {7 this.Items[id] iArray;8 }9 Dsy.prototype.Exists function(id)10 {11 if(typeof(this.Items[id]) "undefined") return false;12 r…

Java里面的arraycopy总结

当我们需要两个数组之和建立一个新的数组的时候&#xff0c;我以为数组也像字符串一样&#xff0c;相加就可以&#xff0c;错了&#xff0c;需要用到arraycopy arraycopy(被复制的数组, 从第几个元素开始复制, 要复制到的数组, 从第几个元素开始粘贴, 一共需要复制的元素个数);…

C#的dapper使用

Dapper是.NET下一个micro的ORM&#xff0c;它和Entity Framework或Nhibnate不同&#xff0c;属于轻量级的&#xff0c;并且是半自动的。Dapper只有一个代码文件&#xff0c;完全开源&#xff0c;你可以放在项目里的任何位置&#xff0c;来实现数据到对象的ORM操作&#xff0c;体…

android什么是回调,Android中的回调是什么?

小编典典回调的概念是在另一个类中完成某些工作时通知类同步/异步。有人称其为好莱坞原则&#xff1a;“不要叫我们&#xff0c;我们叫你”。这是一个例子&#xff1a;class A implements ICallback {MyObject o;B b new B(this, someParameter);Overridepublic void callback…

Andorid之bitmap里面的压缩总结

public Bitmap decodebitmap(Context context, int imageid) {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;// 如果值设为true,那么将不返回实际的bitmap,也不给其分配内存空间,这样就避免了内存溢出。Bitmap bitmap =…

Android -- 创建XML文件对象及其序列化, pull解析XML文件

1. 创建XML文件对象及其序列化 示例代码&#xff1a;&#xff08;模拟以xml格式备份短信到SD卡&#xff09; SmsInfo.java&#xff0c; bean对象 /*** 短信的业务bean* author Administrator**/ public class SmsInfo {private String body;private String number;private int …

.NET大会2021参会笔记

全面拥抱Linux拥抱linux是微软的战略转型。Satya Nadella写的书《refresh》&#xff0c;就提到了MS loves Linux。所以&#xff0c;大会一开始&#xff0c;以然是Scott Hanselman&#xff0c;给我们演示如果在linux上面使用.net。好了&#xff0c;好了&#xff0c;你不用说了&a…

zookeeper配置文件详解

zoo.cfg配置文件 # The number of milliseconds of each tick tickTime2000 # The number of ticks that the initial # synchronization phase can take initLimit10 # The number of ticks that can pass between # sending a request and getting an acknowledgement sync…