在Android中,如果加载过大的Bitmap,可能会造成OOM,所以在加载之前,有必要对其进行压缩处理。
Bitmap压缩大概有两种方式:质量压缩和尺寸压缩。
质量压缩
/**
* bitmap : 要压缩的Bitmap
* options: 质量参数,0 - 100,值越小,图片压缩越厉害,清晰度越低
*/
public static void compress(Bitmap bitmap, int options) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
通过降低图片的质量达到压缩图片,图片像素点个数不会变,改变的是图片位深及透明度等。
还有一种办法可以降低图片质量的,通过改变BitmapOption的色彩模式:
public static void compressBitmap(String filePath, File file) {
BitmapFactory.Options options = new BitmapFactory.Options();
// 默认是ARGB_8888,如果是jpg的话,可以使用RGB_565模式,降低每个像素点占有的内存
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
尺寸压缩
主要利用Android提供的BitmapOption类对Bitmap进行尺寸压缩。先对BitmapOption的几个属性进行了解:
inJustDecodeBounds:
如果将这个值置为true,那么在解码的时候将不会返回bitmap,只会返回这个bitmap的尺寸。这个属性的目的是,如果你只想知道一个bitmap的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。
inSampleSize:
这个值是一个int,当它小于1的时候,将会被当做1处理,如果大于1,那么就会按照比例(1 / inSampleSize)缩小bitmap的宽和高、降低分辨率,大于1时这个值将会被处置为2的倍数。例如,width=100,height=100,inSampleSize=2,那么就会将bitmap处理为,width=50,height=50,宽高降为1 / 2,像素数降为1 / 4。
inPreferredConfig:
这个值是设置色彩模式,默认值是ARGB_8888,在这个模式下,一个像素点占用4bytes空间,一般对透明度不做要求的话,一般采用RGB_565模式,这个模式下一个像素点占用2bytes。
色彩模式:
ALPHA_8
表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度
ARGB_4444
表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节
ARGB_8888
表示32位ARGB位图,即A=8,R=8,G=8,B=8,一个像素点占8+8+8+8=32位,4个字节
RGB_565
表示16位RGB位图,即R=5,G=6,B=5,它没有透明度,一个像素点占5+6+5=16位,2个字节
其中,A代表透明度;R代表红色;G代表绿色;B代表蓝色。
public static void compressBitmap(String filePath, File file) {
int inSampleSize = 2;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = inSampleSize;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
另外我自己写了一个关于Bitmap压缩的库,请参考Android 打造Bitmap压缩工具库。