如何压缩一张图片

970 阅读3分钟

「这是我参与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。