最近想了解一下,图片压缩的一些原理,如一张图片在如何在尽量保持原有质量的情况下对文件尽可能的缩小。 使用GPT
图片压缩的所有方式
图片压缩的常用方式总结如下:
1. 调整图片分辨率:降低图片的像素可以显著减小图片大小。
2. 修改图片文件格式:选择压缩格式如JPG、PNG、WebP等,调整质量参数。
3. 裁剪不必要的图像区域:移除图片中不影响主题的区域。
4. 压缩颜色位数:如从24位降到8位,可大幅减少文件大小。
5. 去除元数据:删除EXIF、XMP等无用的元数据。
6. 图像优化:使用图像处理算法如像素化、模糊化等方式简化图片。
7. 色度子采样:降低色度通道采样率,优先保留亮度信息。
8. 量化与编码:使用DCT、小波等变换,配合量化与熵编码压缩图片数据。
9. 无损压缩:使用统计编码等方法,无损去除图像冗余信息。
10. 图像压缩网络:使用CNN、自动编码器等深度网络进行无损或有损压缩。
11. 在线压缩工具:使用在线工具批处理压缩图片。
12. 批处理:自动化脚本对大量图片进行优化和格式转换。
综合运用各种压缩方式,可以最大程度压缩图片体积,同时尽可能保留重要的图像细节。
对其中第4项比较感兴趣,也比较常用,所以想看看它对具体原理,如果说错的话,请大家指出来哈。我不说图片格式,不贴代码什么的,尽量用浅显易懂的方式记录一下。
RGB888
一张不包含透明度的的全彩图片一个像素占用空间是rgb红绿蓝=8+8+8=24bit=3byte
。如果不经过任何处理,那么一张1080P像素图片除去头信息什么的所占用的储存空间至少是:
3*1920*1080/1024=6075KB
RGB565和RGB555
即每个像素点,存储时R、G、B分别按照5|6|5
或者5|5|5
bit进行存储,原本使用3个byte存放的颜色,现在可以使用2byte
的数据进行存储。咦,那5个bit最多只能放0-31,一个颜色可是用0-255表示哦,那么我们就舍弃8bit中的低位,尽量将高位保存,表示颜色强度。
比如将 RGB888转 为 RGB565:
1 1 1 1 1 1 0 0 | 0 1 1 0 1 1 1 1 0 | 1 1 1 0 1 1 0 1 0 |
---|---|---|
1 1 1 1 1 | 0 1 1 0 1 1 1 | 1 1 1 0 1 1 |
在还原颜色的时候,将低位补0即可。虽然有损失颜色,不过能够减少1/3的大小也是很棒的。
8位图索引图
常用的格式有
格式 | 描述 |
---|---|
GIF | 最常用的8位索引格式,广泛用于网页动图 |
PNG-8 | PNG的8位版本,无损压缩索引图片 |
8位BMP | Windows位图的8位调色板格式 |
8位TIFF | TIFF也可支持8位索引图像 |
ICO | icon图标文件多采用256色模式 |
微软Paint | 早期默认保存为8位BMP格式 |
Palm OS | Palm设备广泛采用8位索引图 |
早期Web | 限制颜色数时多用8位索引图 |
数据结构主要由两个结构组成
- 每个像素中存放的8bit的索引号,0-255之间
- 一个调色板,序号为0-255索引号,对应上面的索引,每个索引号对应一个RGB888的色值。
在渲染颜色的时候,通过每个像素的索引号找到对应的颜色。最多256个颜色。按照这个模式,图片越大,那么按照比例来说压缩率越高,但是,如果原本图片色彩度就比较饱和,图片越大就会越失真。
将全彩色转为8位索引色
这个过程需要需要通过八叉树算法来实现。大概过程就是每个像素遍历,重复将RGB三种颜色转为二进制,将红绿蓝3种颜色的二进制每一位一一对应,然后每一位的三个二进制相加,得到每个像素八个索引值。分别将索引值一层层从高位索引往下直到找到叶子节点。最高有八层,刚好对应8个索引数。最后叶子结点存放像素的RGB色值,并且每次经过叶子节点的数量都会+1。 我们决定了,8为索引图只能最多有256种颜色,当叶子节点的个数超过256的时候,继续往下放已经没有空间继续放了,索引我们需要将新插入的叶子节点值跟老叶子节点进行合并,组成新的叶子节点。响应的色值需要合并。具体算法还没研究。有空再补充一下。
参考文章