因为近期接触了一点嵌入式开发,需要的图片资源格式和以往接触的移动及web开发差别比较大,才有了下面这篇文章。因为比较晦涩,不需要的就可以绕行了。
图像深度、色深、位深的大统一
首先明确一点,图像深度就是色深Color Depth。关于色深和位深Bit-depth,查了很多资料,众说纷纭,有说色深是存储每个像素所用的bit数,而位深是描述通道的属性,那我们通常所说的24位真彩和16位全彩颜色模式,这里的24和16是位深还是色深呢?其实大可不必纠结,可以统称为深度。在显示器的参数中,使用更多的是位深Bit-depth的概念。后面会详细说明深度和具体颜色的关系。
虽然在设计师眼里,PNG、BMP、JPG、JPEG、GIF这些有分辨率属性的点阵图像统统称之为位图,来对应可任意缩放的矢量图,比如SVG,但在工程师,尤其是硬件工程师眼里,位图可能专指BMP格式,所以,一定要和开发人员提前确认,尤其是当涉及到嵌入式开发时,更是如此,越底层越麻烦越受限。
计算机存储图像的原理
因为对于设计师最常用的PS软件在保存BMP格式时有深度的选项,所以下面都以BMP格式为例来说明,尤其是PNG和JPEG都是经过压缩的,具体压缩原理不明,也不作解释。追本溯源,作为只能识别二进制语言的计算机,在进行图像存储时存的是什么呢?像素点。一个8px*8px的图片,一共有64个像素点,计算机在存储时,会针对这64个点依次进行存储。当一个图片保存成hex格式(这是烧入单片机需要的格式),用文本编辑器打开,会发现全部由16进制的编码串组成,这里的每一串编码就是一个像素点,64个编码串解析后呈现出不同的颜色,最终组成了图片。
位深值分配给通道
在BMP格式进行存储的时候,如图所示,系统会有一个关于深度的提示,当我们由基本模式切换到高级模式后,看到16位、24位和32位的具体选项,(X或A)nRnGnBn或RnGnBn的形式表示,(n表示分配给该通道的位数值)。因为每个通道只支持256(0-255)个值,因此,通道拥有的位数值不会大于8(256是2的8次幂)。
举一个16位的说明,R5G6B5,并不是色值的表示方法RGB(5,6,5),而是这16位的位深的通道分配方法,R值支持2的5次幂(32)个值,G值支持2的6次幂(64)个值,B值支持2的5次幂(32)个值,如果16位分配给R8G8B0,但在最终颜色的组成上,65536种颜色会缺少蓝色的元素,只有红和绿的65536种组合。当然,这是极不合理的,只有RGB的组合才能形成彩色,所以位数要平均分配给R,G,B和透明通道Alpha四个通道。 这些通道的设置基本上就是常用设置。
对于Android开发人员,可能不陌生,Bitmap ConfigARGB_8888,对应这里24位的X8R8G8B8,ARGB_4444对应16位的X4R4G4B4,RGB_565对应16位深的R5G6B5,没有透明度。
因此,位深是8位的图,最多只有2的8次幂,也就是256种颜色,远达不到我们对图片的色彩的需要,对于嵌入式系统或者工控领域,显示器才会是16位以下。而当位深达到16位时,支持的颜色就有2的16次幂,65536种颜色,也就是我们说的高彩。而GIF格式的图片,就仅能支持256种颜色,这也是为什么转成GIF有时会失真的原因。其中,32位和24位在RGB通道上是相同的,但8位用来保存Alpha通道。换句话说,在彩色的表现上并无差别,但增加了8位,即2的8次幂(256)阶色的灰度,只是颜色的过渡上更加自然,已经到了人眼无法识别差别的程度。
在PS保存成BMP格式种,提供了1位、4位、8位、16位、24位和32位的选项,这只是常用位深,6位可不可以?当然是可以的,对于6位的图像,可以分配到不同的通道R2G2B2,一共支持4*4*4 共计64种不同的颜色。即使是100*100 一共一万个像素点的图片,对于6位位深而言,也只有64种颜色可以选择。比如我们项目中,显示芯片的规格书中明确规定了支持6-bit,R支持的四个值对应0,1/3R,2/3R和1R,G支持的四个值对应0,1/3G ,2/3G和1G,B支持的四个值对应0,1/3B ,2/3B和1B。怎么转换成设计师能看懂的语言呢,以红色R为例,RGB颜色的表示方法中可以在0-255范围内进行设置,限定的四个值就依次变成了(0,75,150,255),这样看就明确了很多,在进行色彩选择时RGB(75,150,75)这种颜色,或者RGB(0,75,150)等等,只要保证是这四个值的组合就可以了。最简单当方法就是下载一个64位色的色板。
位深与图片尺寸的正相关
说完了位深的分配,再来看存储,也就是对图片尺寸的影响。
bit比特和Byte字节
bit是计算机最基本的存储单元,是二进制的“0”或者“1”,而Byte通常作为存储单位。Byte和bit存在换算关系,1Byte=8bit。
一个8位深的图片,储存每个像素所需要的位数是多少?根据位深的含义,每个像素点可存放8位二进制,每个二进制是一个bit,因此,一个像素需要8bit,也就是1Byte。而16位颜色的图,存储每个像素点,存放的是16位二进制,存储一个像素则需要2Byte。当然了,因为计算机在存储图片时还要存储像素之外的如位图头、位图信息、调色板等其他信息(就像txt文档的尺寸并不仅仅是里面文本所占据的字节的数量),因此并不和我们的换算结果完全相同,只要了解不同位深导致的图片尺寸变化的原因就好。对于BMP格式的图片,不受颜色的约束的,每个色素点,纯黑纯白灰度或者彩色的,存储所占用的字节数是相同的,影响大小的只有位深。下面这张图,所有图片的分辨率都是8*8像素,我用不同后缀的明明白白来区分导出时选择的位深。显而易见的是,只要是16位深,无论灰色、纯红、任意RGB颜色、甚至是渐变,在存储时都是相同的尺寸。而相同分辨率的相同的灰色填充的图片,在保存成24位深和32位深时,相对于16位,尺寸就呈现一个阶梯增加的趋势。
而PNG这种压缩格式,则受制于色彩的丰富度。下面这张图片的对比能很好的说明问题,同样是256px*256px的图片,一个色彩丰富,一个只有两种颜色,在同样选择PNG-24时,尺寸差异很大,但BMP同样是16位位深,则是相同的尺寸。
总结
深度了解图片位深对色彩影响的机制,主要就是在面对具体的项目时,可以更加灵活的选择更合适的图片格式,以及在色彩的选取上,如何才能适应不同的显示芯片。把硬件规格说明书中晦涩难懂的部分转换成设计时需要参考的资源。
转载于:https://juejin.im/post/5d06e4e7f265da1b971a7438