Android平台Bitmap图像压缩
本篇文章用来介绍Android平台的图像压缩方案以及图像编解码的通识性理解
首先来理解几个含义:
像素密度:
像素密度指的是每英寸像素数目,在Bitmap里用mDensity/mTargetDensity,mDensity默认是设备屏幕的像素密度,mTargetDensity是图片的目标像素密度,在加载图片时就是 drawable 目录的像素密度。
色彩模式:
色彩模式是数字世界中表示颜色的一种算法,在Bitmap中是用Bitmap.Config来表示的
ARGB_8888:每个像素占四个字节,A、R、G、B 分量各占8位,是 Android 的默认设置;
RGB_565:每个像素占两个字节,R分量占5位,G分量占6位,B分量占5位;
ARGB_4444:每个像素占两个字节,A、R、G、B分量各占4位,成像效果比较差; Alpha_8: 只保存透明度,共8位,1字节;
Bitmap占用内存:
图片压缩,无非就是考虑将Bitmap占用的内存变小,因此首先要知道你这一张图片占用内存大小是如何计算出来的
Bitmap内存大小 = 图片宽度 x 图片高度 x 每一个像素占用内存
基于此,要想实现内存变小,无非就是从这三个方向下手了
质量压缩
默认从SD卡中加载一张图片
private void loadPic() {
bitmap = BitmapFactory.decodeFile(Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/DCIM/Camera/1476365324913.jpg");
}
日志显示,这个图片的所有数据信息,默认压缩质量是quality=100
可以看到,图片的大小是没有变的,因为质量压缩不会减少图片的像素,它是在保持像素的前提下改变图片的位深及透明度等,来达到压缩图片的目的,这也是为什么该方法叫质量压缩方法。那么,图片的长,宽,像素都不变,那么bitmap所占内存大小是不会变的。
但是我们看到bytes.length是随着quality变小而变小的。这样适合去传递二进制的图片数据,比如微信分享图片,要传入二进制数据过去,限制32kb之内
/**
* 质量压缩
*/
private void qualityY() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int quality = 50;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();
bitmap = BitmapFactory.decodeByteArray(bytes, 0, byteArrayOutputStream.size());
console(bitmap, bytes, quality);
}
采样压缩
设置inSampleSize的值(int类型)后,假如设为2,则宽和高都为原来的1/2,宽高都减少了,自然内存也降低了。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
bitmap = BitmapFactory.decodeFile(Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/DCIM/Camera/1476365324913.jpg",options);
Log.e(TAG, "默认图片尺寸: 大小=" + bitmap.getByteCount()
+ " 宽=" + bitmap.getWidth()
+ " 高=" + bitmap.getHeight()
+ " " + bitmap.getByteCount() / 1024 / 1024 + "M");
最后,说白了,实现压缩,其实就是围绕着整个公式展开的。。。。
Bitmap内存大小 = 图片宽度 x 图片高度 x 每一个像素占用内存