Android压缩Bitmap

本文记录了在Android中对Bitmap进行压缩时遇到的问题及解决方案,包括根据比例压缩和固定长宽压缩两种方法。通过BitmapFactory.Options可以有效地压缩图片,避免OOM错误。同时提到,虽然Bitmap.compress()方法能调整质量,但不直接减少文件大小。ThumbnailUtils类可改变图片尺寸,但压缩后的文件大小可能仍偏大。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这两天在做的一个app对图片进行压缩,踩了几个坑,这里记录一下。

参考文章:http://blog.youkuaiyun.com/an_illusion/article/details/51545012

百度上很多解决方案使用Bitmap.compress()方法来进行图片压缩:

OutputStream out = new FileOutputStream(file);  
bm.compress(Bitmap.CompressFormat.JPEG, 80, out);  
imageView.setImageBitmap(bm);  

第二个参数为保留图片质量(大致这么理解),原图为100,最低为0,但并不是百分比计算压缩率

然而这个方法并没有对输出的图片进行压缩,输出后的图片还是原始大小(据说图像质量会变差,变模糊,但我并没这么觉得,文件大小也没变)

根据比例压缩

后来找到使用BitmapFactory.Options来压缩图片的解决方案,有效并且避免了OOM:

// 从选取相册的Activity中返回后  

Uri imageUri = data.getData();  
String[] filePathColumns = {MediaStore.Images.Media.DATA};  
Cursor c = getContentResolver().query(imageUri, filePathColumns, null, null, null);  
c.moveToFirst();  
int columnIndex = c.getColumnIndex(filePathColumns[0]);  
String imagePath = c.getString(columnIndex);  
c.close();  

// 设置参数  
BitmapFactory.Options options = new BitmapFactory.Options();  
options.inJustDecodeBounds = true; // 只获取图片的大小信息,而不是将整张图片载入在内存中,避免内存溢出  
BitmapFactory.decodeFile(imagePath, options);  
int height = options.outHeight;  
int width= options.outWidth;  
int inSampleSize = 2; // 默认像素压缩比例,压缩为原图的1/2  
int minLen = Math.min(height, width); // 原图的最小边长  
if(minLen > 100) { // 如果原始图像的最小边长大于100dp(此处单位我认为是dp,而非px)  
    float ratio = (float)minLen / 100.0f; // 计算像素压缩比例  
    inSampleSize = (int)ratio;  
}  
options.inJustDecodeBounds = false; // 计算好压缩比例后,这次可以去加载原图了  
options.inSampleSize = inSampleSize; // 设置为刚才计算的压缩比例  
Bitmap bm = BitmapFactory.decodeFile(imagePath, options); // 解码文件  
Log.w("TAG", "size: " + bm.getByteCount() + " width: " + bm.getWidth() + " heigth:" + bm.getHeight()); // 输出图像数据  
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);  
imageView.setImageBitmap(bm); 

如果需要处理大量的Bitmap,需要调用recycle()方法去回收资源,避免内存异常

固定长宽压缩

使用官方的图片压缩类ThumbnailUtils:

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imgUri);
/*计算宽高比,可以加上横竖屏照片的判断*/
int width, height;
if (bitmap.getHeight() > bitmap.getWidth()) {
    float scale = ((float) bitmap.getHeight()) / bitmap.getWidth();
    width = 800;
    height = (int) (width * scale);
} else if (bitmap.getWidth() > bitmap.getHeight()) {
    float scale = ((float) bitmap.getWidth()) / bitmap.getHeight();
    height = 800;
    width = (int) (height * scale);
} else {
    width = 800;
    height = width;
}
/*根据宽高生成bitmap的缩略图*/
Bitmap bm = ThumbnailUtils.extractThumbnail(bitmap, width,height);
File file = new File(Environment.getExternalStorageDirectory().getPath()+"/test.png");
FileOutputStream fos = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();

这个方法将图片尺寸改变,原2M的图片经过压缩后大约500k左右,感觉还是略大,继续寻找让文件更小但不影响清晰度的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值