Android:图片压缩的几种方式
1、前言
- 在
Android
中,图片的压缩对于内存的优化很重要 - 通过这篇文章对
Android
中的几种图片压缩方式进行对比
2、作用
通过图片压缩,实现内存优化,避免OOM
异常
3、内存
图片占用内存计算公式:图片所占内存 = 图片的分辨率
w
* 图片的分辨率h
* 一个像素占用的字节数
获取图片内存大小的代码如下:
public void getBitmapSize(View view) {
File file = Environment.getExternalStorageDirectory();
File originFile = new File(file,"dog.jpg");
Bitmap originBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
int bitmapSize = getBitmapSize(originBitmap);
Log.i("测试","图片所占内存大小->" + bitmapSize);
}
4、分类
- 设置图片格式
- 质量压缩
- 采样率压缩
- 尺寸压缩
4.1、设置图片格式
Android
目前常用的图片格式有png
、jpeg
、webp
等。
- png:无损压缩图片格式,支持背景透明,体积相对较大
- jpeg:有损压缩图片格式,不支持背景透明,体积相对较小
-
webp:是一种同时提供有损压缩和无损压缩的图片格式,无损
webp
平均比png
小26%,有损的webp
平均比jpeg
小30%左右,采用webp
能够在保持图片清晰度的情况下,可以有效减小图片所占的磁盘空间大小。
实验可得:同分辨下的一张图,
jpeg
格式下大小为124kb
,而png
格式下大小为2M
4.2、质量压缩
质量压缩并不会改变图片在内存中的大小,只会改变图片占用磁盘的大小,因为质量压缩改变的是图片的位深和透明度来减少图片占用的磁盘空间大小;
根据内存计算公式知道,宽高都没变,所以内存并不会改变,所以想保持图片的质量同时减少图片所占用的磁盘空间大小,可以选用质量压缩,质量压缩的示例代码如下:
public void qualityCompress(Bitmap.CompressFormat format,int quality){
File file = Environment.getExternalStorageDirectory();
File originFile = new File(file,"dog.jpg");
Bitmap originBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
originBitmap.compress(format,quality,bos);//quality:10=22.57,50=98.12kb,70=122.97kb
int bitmapSize = getBitmapSize(originBitmap);
Log.i("测试","质量压缩后图片所占内存大小->" + bitmapSize);//结果:5760000
try {
FileOutputStream fos = new FileOutputStream(new File(file,"resultQualityImg.jpg"));
fos.write(bos.toByteArray());
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
注:质量压缩关键是
quality
的值,quality
值与图片体积大小成反比,并且由于png
是无损压缩,所以设置quality
无效
4.3、采样率压缩
采样率压缩不仅能压缩图片内存大小,还可以减少图片体积大小,代码如下:
public void sampleRateCompress(int inSampleSize) {
File file = Environment.getExternalStorageDirectory();
File originFile = new File(file, "dog.jpg");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = inSampleSize;
Bitmap resultBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//quality:100=215.38kb,80=50.41kb
int bitmapSize = getBitmapSize(resultBitmap);
Log.i("测试","采样率压缩后图片所占内存大小->" + bitmapSize);//结果:1440000
try {
FileOutputStream fos = new FileOutputStream(new File(file, "resultSampleRateImg.jpg"));
fos.write(bos.toByteArray());
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
采样率压缩的关键是inSampleSize
参数,假如inSampleSize
设置为2
,那么会导致图片的宽高都为1/2
,而内存大小为1/4
;
注:采样率压缩图片也和
quality
参数有关,quality
和图片体积大小成正比,和内存无关
4.4、尺寸压缩
尺寸压缩就是对图片进行一定的缩放,导致宽高的变化,达到压缩图片的目的;和采样率压缩一样,尺寸压缩也是能压缩图片内存大小,还可以减少图片体积大小,代码如下:
public void sizeCompress(int radio) {//radio:5=47.85kb,2=221.39kb
File sdFile = Environment.getExternalStorageDirectory();
File originFile = new File(sdFile, "dog.jpg");
Bitmap bitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
//设置缩放比
Bitmap result = Bitmap.createBitmap(bitmap.getWidth() / radio, bitmap.getHeight() / radio, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
RectF rectF = new RectF(0, 0, bitmap.getWidth() / radio, bitmap.getHeight() / radio);
//将原图画在缩放之后的矩形上
canvas.drawBitmap(bitmap, null, rectF, null);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
result.compress(Bitmap.CompressFormat.JPEG, 100, bos);//
int bitmapSize = getBitmapSize(result);
Log.i("测试","尺寸压缩后图片所占内存大小->" + bitmapSize);//结果:230400
try {
FileOutputStream fos = new FileOutputStream(new File(sdFile, "resultSizeRateImg.jpg"));
fos.write(bos.toByteArray());
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
尺寸压缩的关键是ratio
参数,假如ratio
设置为2
,那么会导致图片的宽高都为1/2
,而内存大小为1/4
;
注:尺寸压缩图片也和
quality
参数有关,quality
和图片体积大小成正比,和内存无关
尺寸
5、采样率压缩和尺寸压缩的区别
从上面的实验结果看出,采样率压缩和尺寸压缩原理似乎的一样的,那么我们从压缩效果展示这两者的区别



- 在分辨率相同的情况下,采样率压缩和尺寸压缩的图片大小相近
- 从采样率压缩和尺寸压缩对比图看出,采样率压缩会让图片更加柔和,而尺寸压缩会更清晰些
6、总结
通过以上的压缩方法分类描述,相信你已经对图片压缩有了更深的了解,那么就可以根据不同的使用场景对相应的图片压缩方式进行选择了