淘先锋技术网

首页 1 2 3 4 5 6 7

一、导言

在嵌入式设备的开发中,有一些嵌入式设备对于图片的格式和大小有限制,有些在项目中使用到的图片资源需要严格限制图片的位深度。
但常规方式压缩图片会使得图片质量下降严重,我们需要效率同时又能最大程度保留图片质量的方法。通过这篇文章你能简单的了解计算机的颜色模式,并学习如何通过小工具转换PNG图片的位深度。

二、计算机颜色模式

常见的颜色有 8位 16位 24位 32位色,其中24位及以上称为真彩,是PC上最常用的颜色,其他基本用于嵌入式系统或一些工控领域,详情见下表:

Bit 深度色彩数备注
12monochrome
24CGA
416EGA
8256VGA
1665,536High Color, XGA
2416,777,216True Color/真彩色, SVGA
3216,777,216True Color + Alpha Channel/控制透明度

1.色彩组成

三原色指色彩中不能再分解的三种基本颜色,在显示器中用到的就是光学三原色(RGB):红、绿、蓝 。光学三原色混合后,组成显示屏显示颜色,三原色同时相加为白色,白色属于无色系(黑白灰)中的一种。

图1 三原色

2.RGB表示

那么在计算机中,我们以2进制保存数值,对于颜色来说,假设我们给三原色每种颜色分配8bit来表示亮度,那么R、G、B这三个通道各能以0-255(8位的表示范围)显示颜色的多少(也就是亮度),在通常情况下,RGB各有256级亮度,按照计算,256 级的RGB色彩总共能组合出约1678万种色彩,即256×256×256=16777216。通常也被简称为1600万色或千万色。也称为24位色(2 的24次方)。
同时24位色又被称为真彩色,因为它可以达到人眼能分辨的极限。32位色就并非是2的32次方种色彩,它其实也是1600万色,不过它增加了256阶颜色的灰度也就是8位透明度,但是增加了8位透明度,就规定它为32位色。
图2 RGB模型

3.像素值

图片可以看做是一个二维数组构成的矩阵,每个像素点的值就是这个点对应的颜色。

图3 像素矩阵
在软件中,我们通常使用十六进制颜色码来表示一种颜色,我们确定一种颜色后,根据色盘确定对应的RGB值,得到的颜色码就能唯一的标识这种颜色(同一标准下)。
以24位真色彩为例,图4的粉色是由R(238) G(162) B(164)合成的,那么把每个对应的值转换成十六进制就得到#EEA2A4这个颜色码。那么在不同的设备上使用这个颜色码也会得到同样的效果(显示设备硬件可能有所差异),不会有二义性(软件层面)。

图4 色轮
但是需要注意的是,当我们在使用8位深的图片时,它的表示如下:
2 8 = 2 2 ( B ) ∗ 2 3 ( G ) ∗ 2 3 ( B ) = 256 2^8 = 2^2 (B)* 2^3 (G)* 2^3 (B)= 256 28=22B23G23B=256

我们想象现在有一个巨大的调色盘,那么8位深度意味着你有256种颜色供你取用作画。这也意味着在某些位深限制下(如16位、8位),三个通道
位数并不是均匀分布的。
不管格式如何,位深度限制会使得图片清晰度下降,因为每个像素所能承载的信息变少了,如图5所示同一张图片在三种位深度下的显示效果:
图5 位深度变化
我们可以明显看到随着位深越低,颜色过渡逐渐丢失,特别在4位深时变成了几个明显的色块,我们如果按照之前的理解,4位深应该被拆分为三个
通道,变成类似如下的结构:
2 4 = 2 1 ( B ) ∗ 2 2 ( G ) ∗ 2 1 ( B ) = 16 2^4 = 2^1(B)* 2^2(G)* 2^1(B)= 16 24=21B22G21B=16
显然这样做是不合理的,这会限制每个像素的信息,最终只能有16种固定的颜色分配,那么如果你需要显示一张图片,上面恰好有16种不同的颜
色,有什么办法在4位深的情况下保证每种颜色都不失真呢?
答案很简单,就像我们前面提到的调色盘的概念,我们选取需要的16种颜色放在调色盘中,用4bit来标志每种颜色,这样就能准确的显示每种颜色,可以用
图6的例子来感受一下:
图6 调色盘
现在有两种调色盘选择,让你绘制图中的草地,我们选用右边的调色盘明显更佳 ,虽然左边的调色盘覆盖的颜色区域更广,但是很多对于这张图是无用的,当然这是比较极端的情况,但是可以帮助我们理解调色盘的作用。
这时候RGB彩色图像转换为索引彩色图像。图像中保存的不再是各个像素的彩色信息,而是从图像中挑选出来的具有代表性的颜色编号,每一编号对应一种颜色,图像的数据量也因此减少,这对彩色图像的传播非常有利。

三、图片压缩工具

综上所述,16色颜色的调色板可以根据图片的整体颜色,统计抽取出最代表性的16种颜色,这点Photoshop软件做得比较好,但是程序员就该有程序员的样子,总不能每处理一张图片就拿出你的PS吧。
要知道位深的限制并不是毫无意义的,这取决于设备支持(例如MAZ项目中图片位深最多为4bit),更重要的是这样能压缩图片的大小,好的调色盘可以在极大减少图片占用的情况下,只轻微的影响图片的质量。
当然这样的说法没有量化,我们这时候就要介绍这款图片压缩工具:
pngquant

1.优势

pngquant是一个命令行实用程序和一个用于对 PNG 图像进行有损压缩的库。
转换显著减小了文件大小(通常高达 70%)并保留了完整的 Alpha 透明度。生成的图像与所有网络浏览器和操作系统兼容。如图7所示:
图7 压缩效果
它有如下特性:

  • 使用矢量量化算法的组合生成高质量的调色板。
  • 与标准 Floyd-Steinberg 相比,独特的自适应抖动算法向图像添加的噪声更少。
  • 易于与 shell 脚本、GUI 和服务器端软件集成。
  • 用于实时处理/大量图像的快速模式

2.参数说明

可以通过pngquant -h来查看完整的选项列表,下面列出一些常见选项。

--ext new.png
 
#为输出文件名设置自定义扩展名。默认情况下使用-or8.png或-fs8.png。
 
--quality min-max
 
#指示使用达到或超过最高质量pngquant所需的最少颜色。如果转换导致质量低于最低质量,则图像将不会被保存(如果输出到标准输出,将输出 24 位原始图像)并将以状态码 99 退出。
 
#min和max是 0(最差)到 100(完美)范围内的数字,类似于JPEG。
#例如:
pngquant --quality = 65-80 image.png
 
--speed N,-sN
#从 1(蛮力)到 10(最快)的速度/质量权衡。默认值为 3。速度 10 的质量降低 5%,但比默认值快 8 倍。
 
--version
#将版本信息打印到标准输出。
 
-
#从标准输入读取图像并将结果发送到标准输出。
 
--
#停止处理参数。这允许使用以 . 开头的文件名-。如果您pngquant在脚本中使用,建议将其放在文件名之前:
 
pngquant $OPTIONS -- "$FILE"

3.位深度转换

那么我们要将一张32位深的png图片转换成4位深,就运行如下代码:

.\pngquanti.exe --transbug --force 16 --ext .png .\xxx.png

图8 效果对比

转换后依然保持比较好的清晰度,没有特别明显的质量影响,但是体积缩小了90%,如图9所示:
图9 大小对比

四、总结

通过pngquant我们能便捷的转换位深度,或是压缩图片的大小,这对于一些空间有限的嵌入式设备来说是很有意义的,当然应用在项目中时,还可以写一个脚本,批量将文件夹中的图片文件进行压缩。
当然对于计算机如何处理图片类型的文件也是值得我们了解的,这样便于我们更好的理解和针对性的给出方案,当然本文中关于颜色模式的介绍较为浅显,欢迎指正补充。