Bitmap 的几种压缩方式

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

代码如下

  1. ByteArrayOutputStream baos =  new  ByteArrayOutputStream();
  2. image.compress(Bitmap.CompressFormat.JPEG,  100 , baos);
  3. int  options =  100 ;
  4. while  ( baos.toByteArray().length /  1024 > 32 ) {
  5. baos.reset();
  6. image.compress(Bitmap.CompressFormat.JPEG, options, baos);
  7. options -=  10 ;
  8. }
  9. ByteArrayInputStream isBm =  new  ByteArrayInputStream(baos.toByteArray());
  10. Bitmap bitmap = BitmapFactory.decodeStream(isBm,  null ,  null );

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

2、采样率压缩法:

代码如下

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

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

  1. BitmapFactory.Options newOpts =  new  BitmapFactory.Options();
  2. newOpts.inJustDecodeBounds =  true ;
  3. Bitmap bitmap = BitmapFactory.decodeFile(path,newOpts);
  4. newOpts.inJustDecodeBounds =  false ;
  5. int  w = newOpts.outWidth;
  6. int  h = newOpts.outHeight;
  7. //计算出取样率
  8. newOpts.inSampleSize = be;
  9. 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);
        } 
时间: 2024-08-09 06:34:33

Bitmap 的几种压缩方式的相关文章

unity打包AssetBundle包的几种压缩方式介绍

Unity资源打包目的就是把一部分游戏资源或是需要热更的资源从游戏安装包中分离出来,降低安装包的大小,在热更或加载资源时再从服务器下载所需资源,当然已经下载的资源和不需要更新的资源不需要重复下载,Unity的打包可以也只能在unity的编辑器下进行,比如可以用unity提供的接口如下面代码所示: public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetB

转:Bitmap的六种压缩方式

文章转自:http://blog.csdn.net/harryweasley/article/details/51955467 Android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: 图片长度 x 图片宽度 x 一个像素点占用的字节数 以下是图片的压缩格式: 其中,A代表透明度:R代表红色:G代表绿色:B代表蓝色. ALPHA_8 表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只

bitmap的六种压缩方式,图片压缩

转载请注明出处,谢谢:http://blog.csdn.net/harryweasley/article/details/51955467 android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: 图片长度 x 图片宽度 x 一个像素点占用的字节数 以下是图片的压缩格式: 其中,A代表透明度:R代表红色:G代表绿色:B代表蓝色. ALPHA_8 表示8位Alpha位图,即A=8,一个像素点占用1个字节,它

浅谈android中加载高清大图及图片压缩方式(二)

这一讲就是本系列的第二篇,一起来聊下关于android中加载高清大图的问题,我们都知道如果我们直接加载原图的话,一个是非常慢,需要等待一定时间,如果没有在一定的时间内给用户响应的话,将会极大影响用户的体验.另一个是如果你的手机内存小的话,可能会直接崩溃.这也就是直接加载高清原图问题.遇到这些问题很容易想到的一点就是图片压缩,本篇文章也就是讲述图片压缩方式来实现加载高清大图的效果.但是现在问题就来了,通过上篇博客我们知道,手机的分辨率有很多,如何保证我同一张图片在不同分辨率的手机上能适当的压缩比例

linux常见的几种压缩命令tar,gz,zio,bz2

Linux下压缩.解压命令五花八门,不像在windows下一个winrar打遍天下无敌手,清一色的.rar .zip格式. 比如,Linux下常用的tar tar.gz tar.bz2 .Z等等不一而足.而每种压缩和解压方式所耗CPU时间和压缩比率也差异甚大.在此我一一列举,希望不当之处,敬请各位指教. --------------------------------------------------------------------------------------------- 1 各

Bitmap有效的压缩方式

在Android开发中我们都会遇到在一个100*100的ImageView上显示一张过大的图片,如果直接把这张图片显示上去对我们应用没有一点好处反而存在OOM的危险,所以我们有必要采用一种有效压缩方式来显示上去. private void calculateBitmapInSimpleSize() { Bitmap _bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_homepage); getBitmapDa

垃圾回收(GC)的三种基本方式

垃圾(Garbage)就是程序需要回收的对象,如果一个对象不在被直接或间接地引用,那么这个对象就成为了「垃圾」,它占用的内存需要及时地释放,否则就会引起「内存泄露」.有些语言需要程序员来手动释放内存(回收垃圾),有些语言有垃圾回收机制(GC).本文就来讨论GC实现的三种基本方式. 其实这三种方式也可以大体归为两类:跟踪回收,引用计数.美国IBM的沃森研究中心David F.Bacon等人发布的「垃圾回收统一理论」一文阐述了一个理论:任何垃圾回收的思路,无非以上两种的组合,其中一种的改善和进步,必

Winform下压缩方式的选取

1. 压缩类型的选择 依据压缩方式的不同,压缩分为有损压缩和无损压缩.其中MP3一类的文件在一定程度的有损压缩下,人的感知不是十分明显而且还是MP3文件的体积相对减小.无损压缩就是类似于Zip,Rar一类的压缩方式,通过字典保存重复值并以一定的坐标映射方式制定对应的值,例如 重复字符串占20位,而映射的字符串仅仅占2位,这样就达到了压缩的目的,压缩率就是要看重复值出现的概率.这仅仅是压缩的一种方式,还有许多专门针对特定文件的压缩算法. 2. 7z压缩 7-Zip 是一款 开源 软件.大多数源代码

关于popupwindow的两种实现方式

http://104zz.iteye.com/blog/1685389 android PopupWindow实现从底部弹出或滑出选择菜单或窗口 本实例弹出窗口主要是继承PopupWindow类来实现的弹出窗体,布局可以根据自己定义设计.弹出效果主要使用了translate和alpha样式实现,具体实习如下: 第一步:设计弹出窗口xml: Xml代码   <?xml version="1.0" encoding="utf-8"?> <Relativ