写在前面:之前一直没有这个概念,以为像素就是十六进制如 #FFFFFF,或者r gb(255,255,255) 即可实现颜色定义,理解相当肤浅,接触到一个物联网项目,写底层的童鞋让我把16位如 0*FFFF转为24位去显示在浏览器,同时下发给硬件的时候再转回十六位给他,瞬间干懵逼,特意花了两个小时去查阅相关资料,终于有了一知半解,汇总以备忘。
引用了CSDN与知乎优秀总结:
博主:丁香树下丁香花开:8位, 16位,24位,32位图片显示原理及对比 https://blog.csdn.net/csdn66_2016/article/details/82850695文章浏览阅读5.9w次,点赞50次,收藏169次。 我们都知道一张图片可以保存为很多种不同的格式,比如bmp/png/jpeg/gif等等。这个是从文件格式的角度看,我们抛开文件格式,看图片本身,我们可以分为8位, 16位, 24位, 32位等。 单击右键,属性->详细信息即可查看图片位深度:8位: 2^8 = 2^2(B) 2^3(G) 2^3(R) = 256 (256色) 可以总共显示256种颜色16位:..._24位图片https://blog.csdn.net/csdn66_2016/article/details/82850695
博主:wkd_007 :bmp位图格式详细介绍-1/4/8/16/24/32bit、存储格式等 bmp位图格式详细介绍-1/4/8/16/24/32bit、存储格式等_bmp文件详解-CSDN博客文章浏览阅读1.5w次,点赞23次,收藏88次。详细介绍bmp位图文件的四个部分:位图文件头、位图信息头、调色板、位图数据,并且结合位图文件数据举例说明了什么是位图文件,bmp位图看这篇文章就差不多了_bmp文件详解https://blog.csdn.net/wkd_007/article/details/128214157
以及知乎:16位色对24位色的映射? - 知乎
总结一些概念性知识点:希望能从概念,实操,代码说明上对图片位数理解更深入一些
一,位图
位图图像(bitmap),亦称为点阵图像或栅格图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。当放大位图时,可以看见赖以构成整个图像的无数单个方块。扩大位图尺寸的效果是增大单个像素,从而使线条和形状显得参差不齐。
二,位深
常用的8位图,24位图,其实就是在说这个图像,是用了多少位二进制 来表示色值。位深指的就是二进制的位数(bit)。
比如,位深只有1位的话,那就只能用0和1表示颜色,也就是0(黑)和1(白)两种颜色。
通常计算机用一个字节(8位)来控制一种颜色的强度,那要表示R、G、B就需要24位(3*8),这也是最常见的图像位深。 【引自知乎:16位色对24位色的映射? - 知乎】
三,不同位深图片的存储原理
8位: 2^8 = 2^2(B) 2^3(G) 2^3(R) = 256 (256色) 可以总共显示256种颜色
16位:2^16 = 2^5(B) 2^6(G) 2^5(R) = 65536 可以总共显示65536种颜色
24位:2^24 = 2^8(B) 2^8(G) 2^8(R) = 16777216 可以总共显示16777216种颜色
32位:Alpha透明度 + 24位
区别:
当8或16位深度时,单个原始颜色 (R/G/B)最大只能表示为(0~2^3)/(0~2^6), 无法满足(0~0xff)的范围,所以显示的颜色范围有限。
当24位深度时,使用24bit显示一个像素点, 由8bit Red, 8bit Green, 8bit Blue组合颜色而成,每一个原始颜色(R/G/B)都可以完全显示(0~0xff),所以24位及以上,我们就叫做真彩色
当32位深度时,与24位相同,可以显示所有的颜色,同时多了一个透明度值。
【以下位图介绍引自知乎:16位色对24位色的映射? - 知乎】
1、24位图
24位图每个像素占用3个字节,每一个原始颜色(R、G、B)都使用8位表示,因此占用24位(8*3)。每个原始颜色都能完整显示256阶颜色,其表示的色彩有16777216种颜色(256^3)。由于人眼最多可以识别100多万种颜色,因此也将24位叫做真彩色。
图中像素的信息为:1111 0011 1110 1010 0011 0111
2、16位图
16位图每个像素占用2个字节,也是通过RGB数值来表示颜色,与24位图原理类似。根据二进制的特征,低位数值的变化对于整体数值影响不大,因此将8位缩减,而达到减少字节的效果。在实际显示时,通过特定的转换方式将16位再扩展为24位。概括来说,就是移位补0的方式。
常见的16位图有两种格式,分别为RGB565、RGB555。
- RGB565
RGB565的存储信息方式就是R-5位、G-6位、B-5位。565存储方式下,示例的像素点信息为
转换为24位时,R-后3位补0、G-后2位补0、B-后3位补0:
实际显示的颜色信息为:1111 0000 1110 1000 0011 0000,换算为RGB(240,232,48)。
- RGB555
RGB555的存储信息方式是,最高位不用,每个颜色都占5位。555存储方式下,示例的像素点信息为:
转换为24位时,每个颜色后3位补0,换算为RGB还是(240,232,48)。
对比色值可以看到,转换之后与原始颜色的RGB数值差异是较小的。只是在有颜色过渡的情况下,会由于丢失细节数据,而导致过渡相对不平滑。但对于本身像素间差异就比较大的图片不会有太大影响,但每个像素点可以节约1个字节的空间,对于大尺寸图片来说存储优势还是比较明显的。
3、8位图
8位图的像素信息与以上二种是完全不同的,采用的是索引色,单个像素存储的值不是直接的RGB色值,而是一个映射关系。这里插一个概念:如果像素信息就是RGB色值,叫做直接色。
8位图的图片信息中先存储了一个256行的色彩数列,单个像素信息存储的值指向对应的行,读取这一行存储的RGB值进行显色,因此称为索引色。假设某一个像素的的值为4,那这个像素就与数列的第4行形成映射,在屏幕显示的实际颜色是就是第4行的RGB值。
四,转换实战:硬件16位颜色转24位给浏览器显示
(因为楼主是PHPer,故从php的角度进行转换,其他语言同理)
转换一:硬件上报16位,程序解析成24位
条件:假使硬件童鞋下发给我们指令颜色为565格式的16位的数据,如:0*FFFF
第一步:0*FFFF 十六进制转二进制:为 1111111111111111
第二步:按照R-后3位补0、G-后2位补0、B-后3位补0,可先切换为 11111 111111 11111,分别补3个0,2个0,3个0,即为 11111000 11111100 11111000,二进制转十进制,即为:rbg(248,252,248)
【理论上硬件下发的是白色,也就是应该转成 rgb(255,255,255),但是因为位移关系,造成的细微误差可以忽略不计,因为本身就是为了减少字节长度】
转换二:程序设置颜色为24位,下发给硬件需转成16位
条件:假使我们设置的颜色为rgb(255,255,255),需要下发给硬件
第一步:255,255,255 转二进制:11111111 11111111 11111111
第二步:按565格式,将每个二进制的数据,8字节按323进行减少,即为:11111 111111 11111,再由二进制转十六进制:即为 0*FFFF
至此,转换流程ok!