Android Bitmap尺寸压缩和质量压缩
作者:陆金龙
发表时间:2017-10-22 12:04
Bitmap尺寸压缩
在图片显示或处理时,经常需要创建Bitmap对象。由于Bitmap占用内存是跟图片的像素点数量直接相关的,因此图片尺寸的大小对内存的占用有很大的影响。如2560x3840尺寸的照片,如果ARGB_4444格式直接加载到Bitmap,占用内存中2560x3840x2/(1024x1024)=18.75M,如果以ARGB_8888格式直接加载则占用内存37M。Android虚拟机默认分配给应用的内存为16M,这样很容易就发生OOM(OutOfMemory)错误。
在满足显示要求的前提下,应尽量减小Bitmap的宽高尺寸。
从图片文件读取为Bitmap对象,可根据需要显示的大小,计算出采样率,然后创建出合适尺寸的Bitmap对象,尽可能减小对内存的占用。
//*
* 根据采样率从文件获取位图图片
*
* @param srcPath 文件路径
* @param inSampleSize 采样率 图片的采样率: 数值越高,图片像素越低。
* @return 通过采样率进行尺寸压缩的位图对象
public static Bitmap getBitmap(String srcPath, int inSampleSize) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = inSampleSize;
opts.inPurgeable = true;// 同时设置才会有效
opts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
Bitmap resizeBmp = BitmapFactory.decodeFile(srcPath, opts);
return resizeBmp;
}
//*
* 根据需要显示的宽度获取合适大小的位图
*
* @param srcPath 文件路径
* @param width 图片需要显示的宽度
* @return 通过采样率进行尺寸压缩的位图对象
public static Bitmap getBitmap(String imagePath, int width) {
// 获取采样率
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; // 只获取图片的大小信息,不将整张图片载入在内存中,避免内存溢出
BitmapFactory.decodeFile(imagePath, options);
inSampleSize = (int)Math.ceil(options.outWidth/width); // 计算像素压缩比例
// 加载原图
options.inJustDecodeBounds = false;
options.inSampleSize = inSampleSize; // 设置为刚才计算的压缩比例
opts.inPurgeable = true;// 同时设置才会有效
opts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
Bitmap resizeBmp = BitmapFactory.decodeFile(imagePath, options); // 解码文件
return resizeBmp;
}
注:
* BitmapFactory.Options.inPurgeable;
*
* 如果 inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap
* 用于存储Pixel的内存空间在系统内存不足时可以被回收,
* 在应用需要再次访问Bitmap的Pixel时(如绘制Bitmap或是调用getPixel),
* 系统会再次调用BitmapFactory decoder重新生成Bitmap的Pixel数组。
* 为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据。
*
* 在inPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收,
* 这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象,
* 不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同,
* 200个bitmap足以使大部分的设备重新OutOfMemory错误。
* 当isPurgable设为true时,系统中内存不足时,
* 可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory 错误
Bitmap质量压缩
在图片文件上传时,不希望图片太大,占用过多浏览,可以对图片适当进行质量压缩,另存为文件再上传。
//*
* 质量压缩减小图片文件的存储大小
*
* @param bmp
* @param file
public static void compressBitmap(Bitmap bmp, File file) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.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();
}
}
//*
* 质量压缩减小图片文件的存储大小
*
* @param bmp
* @param file
* @param quantity 压缩质量 1-100, 100为不压缩 ,值越小 压缩越厉害
public static void compressBitmap(Bitmap bmp, File file, int quantity) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, quantity, baos);//如果需要透明 使用Bitmap.CompressFormat.PNG
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}