「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」
如何压缩一张图片
图片的应用场景就太多了,如何处理好一张图片,保证清晰度的同时占用空间又小,成为首要的追求目标,那么如何压缩一张图片?
图片格式
不知道大家有没有遇到这样的场景,用压缩工具压缩一个100M的JPG图片文件夹,压缩后大概就在95M左右,而其它文件则可以压缩50M以上。
这是因为JPG是已经压缩过的一种格式。
图片也有众多的编码格式,比如说,jpg、png、bmp等都是我们常见的图片格式,那么这些图片格式有什么区别呢?
-
JPG是一种有损压缩的编码,它出了色彩空间转换,采样率,分块处理技术后,还采用哈夫曼(Huffman)编码方式。 由于会将RGB颜色数组换算成YUV然后降低UV的采样率,所以这是一种压缩算法。
-
png是一种无损压缩编码,增加透明度的通道,能在不失真的情况下降低图像文件的大小,由于是无损压缩,并且用了透明度支持,所以相同的文件下,要比JPG内存占用大
-
BMP代指位图(Bitmap),是未经过压缩的编码,所以它占用的内存很大。
压缩方式
-
图片大小
-
图片质量
-
图片编码
从根本上讲,图片压缩总是围绕着这三个方向进行开展的。
由于现在设备相机拍照的分辨率很高,虽然图片的质量有所提高,但原始图片就会占用很大空间,如果是在网络上传输,或者进行简单的预览,就没有必要,比如上传头像等场景中。所以我们会压缩图片的大小,使其在满足业务场景下也减少大小占用。
在Android中压缩图片大小的算法举例:
public static void compressBitmapToFile(Bitmap bmp, File file){
// 压缩的倍数
int ratio = 2;
Bitmap result = Bitmap.createBitmap(bmp.getWidth() / ratio, bmp.getHeight() / ratio, Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Rect rect = new Rect(0, 0, bmp.getWidth() / ratio, bmp.getHeight() / ratio);
canvas.drawBitmap(bmp, null, rect, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
result.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中的方法举例
Bitmap bitmap;
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
//质量压缩方法,调节options的值,这里100表示不压缩,把压缩后的数据存放到baos中
options.inSampleSize = computeSize();
图片编码上面,除了常见的JPG、PNG之外,目前很多大公司都开始使用webp格式,它具有更优的图像数据压缩算法,所以体积更小。
在AndroidStudio中将图片转换成webp格式。
对着图片文件右键,然后点击 Convert to WebP,然后调节设置就可以了。
如何加载webp,在Android中不能像加载普通图片一样加载webP,目前主流的图片加载框架都已经支持webp。