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

中图片是以形式存在的,那么所占内存,直接影响到了应用所占内存大小,首先要知道所占内存大小计算方式:
图片长度 x 图片宽度 x 一个像素点占用的字节数
以下是图片的压缩格式:

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

文章插图
其中,A代表透明度;R代表红色;G代表绿色;B代表蓝色 。
表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度
表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节
表示32位ARGB位图,即A=8,R=8,G=8,B=8,一个像素点占8+8+8+8=32位,4个字节
表示16位RGB位图,即R=5,G=6,B=5,它没有透明度,一个像素点占5+6+5=16位,2个字节
我是用的小米手机2s来测试的,从sd卡取出一个照片,如下所示:
bit = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/DCIM/Camera/test.jpg");Log.i("wechat", "压缩前图片的大小" + (bit.getByteCount() / 1024 / 1024)+ "M宽度为" + bit.getWidth() + "高度为" + bit.getHeight());
出来的log是:
将取得的进行压缩,下面开始说,的几种压缩方式 。
1.质量压缩
bitmap的六种压缩方式,图片压缩

文章插图
ByteArrayOutputStream baos = new ByteArrayOutputStream();int quality = Integer.valueOf(editText.getText().toString());bit.compress(CompressFormat.JPEG, quality, baos);byte[] bytes = baos.toByteArray();bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);Log.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024 / 1024)+ "M宽度为" + bm.getWidth() + "高度为" + bm.getHeight()+ "bytes.length=" + (bytes.length / 1024) + "KB"+ "quality=" + quality);
其中是从获取的数字,可以从0–100改变,这里出来的log是:
bitmap的六种压缩方式,图片压缩

文章插图
可以看到,图片的大小是没有变的,因为质量压缩不会减少图片的像素,它是在保持像素的前提下改变图片的位深及透明度等,来达到压缩图片的目的,这也是为什么该方法叫质量压缩方法 。那么,图片的长,宽,像素都不变,那么所占内存大小是不会变的 。
但是我们看到bytes.是随着变小而变小的 。这样适合去传递二进制的图片数据,比如微信分享图片,要传入二进制数据过去,限制32kb之内 。
这里要说,如果是press(.PNG, , baos);这样的png格式,就没有作用了,bytes.不会变化,因为png图片是无损的,不能进行压缩 。
【bitmap的六种压缩方式,图片压缩】还有一个属性是,.WEBP格式,该格式是自己推出来一个图片格式,更多信息,文末会贴出地址 。
2.采样率压缩
BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/DCIM/Camera/test.jpg", options);Log.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024 / 1024)+ "M宽度为" + bm.getWidth() + "高度为" + bm.getHeight());
出来的log是
设置的值(int类型)后,假如设为2,则宽和高都为原来的1/2,宽高都减少了,自然内存也降低了 。
我上面的代码没用过. = true; 因为我是固定来取样的数据,为什么这个压缩方法叫采样率压缩,是因为配合,先获取图片的宽、高【这个过程就是取样】,然后通过获取的宽高,动态的设置的值 。
当设置为true的时候,通过或者解码图片时,将会返回空(null)的对象,这样可以避免的内存分配,但是它可以返回的宽度、高度以及 。