在我们做项目中,为了减少图片占用的内存,就需要把图片给进行压缩,而图片在我们Android里又是以bitmap形式存在,所以我们要对bitmap进行压缩,首先要知道bitmap的内存占用的计算公式。计算公式:长度×宽度×1像素占用的字节数
bitmap压缩有四种方式:
Bitmap.config ALPHA_8 表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度
Bitmap.config ARGB_4444 表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节
Bitmap.config ARGB_8888 表示32位ARGB位图,即A=8,R=8,G=8,B=8,一个像素点占8+8+8+8=32位,4个字节
Bitmap.config RGB_565 表示16位RGB位图,即R=5,G=6,B=5,它没有透明度,一个像素点占5+6+5=16位,2个字节
ps: A(alpha)透明 R(red)红色 G(green)绿色 B(blue)蓝色
代码说明:
//获取一张图片,进行压缩
bit = BitmapFactory.decodeFile(Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/DCIM/Camera/test.jpg");
Log.i("wechat", "压缩前图片的大小" + (bit.getByteCount() / 1024 / 1024)
+ "M宽度为" + bit.getWidth() + "高度为" + bit.getHeight());
bitmap共计五种压缩方式,接下来就依次说一下。
1.质量压缩
经过质量压缩的图片大小不会改变因为质量压缩不会减少图片的像素 ,它是在保持像素的前提下改变图片的位深及透明度等属性来达到压缩图片的目的,所以说这个方法叫质量压缩,既然图片的长宽和像素都不变,那么bitmap占用的内存大小也是不会改变的。
ps:如果图片是png模式那么长度就不会变化,因为png是无损的,不能进行压缩。
2.采样率压缩
在我们设置了inSampleSize的值(int类型)后,如果inSampleSize=4,那么宽高都是原来的1/4,既然宽高都减少了,内存自然也就降低了
为什么这个压缩方法叫采样率压缩呢?是因为配合inJustDecodeBounds,先获取图片的宽、高(取样的一个过程),然后通过获取的宽高,动态的设置inSampleSize的值。
3.缩放法压缩(martix)
代码说明:
Matrix matrix = new Matrix();
//宽高都为原来的1/2, 所以结果就会为0.5*0.5=1/4
matrix.setScale(0.5f, 0.5f);
bm = Bitmap.createBitmap(bit, 0, 0, bit.getWidth(),
bit.getHeight(), matrix, true);
Log.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024 / 1024)
+ "M宽度为" + bm.getWidth() + "高度为" + bm.getHeight());
bitmap的长度和宽度分别缩小了一半,图片大小缩小了四分之一。
4.RGB_565法
代码说明:
BitmapFactory.Options options2 = new BitmapFactory.Options();
options2.inPreferredConfig = Bitmap.Config.RGB_565;
//获取图片
bm = BitmapFactory.decodeFile(Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/DCIM/Camera/test.jpg", options2);
//压缩后的大小
Log.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024 / 1024)
+ "M宽度为" + bm.getWidth() + "高度为" + bm.getHeight());
从上边的代码可以看出图片大小直接缩小了一半,长度和宽度也没有变,相比argb_8888减少了一半的内存。
ps:由于ARGB_4444的画质很low所以如果没有对图片有透明度要求的话可以改为RGB_565,相比ARGB_8888会少占用一半的内存
5.createScaledBitmap
代码说明:
//给出固定的宽高值
bm = Bitmap.createScaledBitmap(bit, 150, 150, true);
Log.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024) + "KB宽度为"
+ bm.getWidth() + "高度为" + bm.getHeight());
ps:这个是将图片压缩为用户设定的长宽度,如果设定的和原本的相差太多,图片会很不清晰。