> 文档中心 > RGB色彩空间

RGB色彩空间

我们平时接触最多的色彩空间 是 RGB,上学的时候就学过三原色,所有的颜色可以通过三原色产生,这 三原色 就是 Red (红),Green(绿),Blue(蓝)。

做 web 前端的同学也会经常用过 RGB 来指定 页面元素的 颜色。RGB 格式目前主要有两类:

  1. 像素格式,这是我们比较常用的格式,R,G,B 分别分开用N个位来表示。例如 RGB24格式 中 R 占 8位,G 占 8位,B 占8 位,所以一个像素占 24位。这种格式可以混合生成 256 256 256 = 16,777,216 种颜色,但缺点是占用空间大。

  2. 索引格式,RGB 的值是一个索引,不是真正的颜色值,例如 RGB 的值 占 1位,那只有两个值 0 跟 1,通常用于黑白颜色,这种情况下 一个像素只占 1位,大大节省了空间。0 跟 1 到底是什么颜色,是通过 索引表(也叫调色板)来定位的,不一定是 黑白,也可以是其他的颜色。所以叫索引格式。

    只占 1 位的 RGB 成为 RGB1,还有 RGB4 占 4 位,索引表有 15种颜色, RGB8 占 8 位,索引表有 256 种颜色。

扩展知识:不需要 索引表/调色板 的 RGB 模式 称为 真彩色


现在还在用 RGB 模式的 应该只有 BMP 文件格式了,BMP 全称 Bitmap-File,是微软出的 图像文件格式。所以接下来 讲一下 BMP 的文件格式。

由于 BMP 格式比较简单,所以使用 HxD 即可,这是一个 16进制查看器,功能非常强大,用 HxD 打开 juren.bmp 图片,如下:

juren.bmp 下载地址 :百度网盘,提取码:k1ow

BMP 格式 由以下部分组成。

1,BMP文件头(14 bytes) ,存放一些 文件 相关的信息。

2,位图信息头,通常是 40 bytes 大小,也可以理解成 图像信息头,存放一些图像相关的信息,例如宽高之类的数据。

3,调色板,大小由 颜色索引决定,本文的 juren.bmp 是 RGB24 模式,真彩色,没有用到 调色板,所以这个区域是0字节

4,位图数据,对于本文的 juren.bmp 来说,里面就是 RGB 数据,一个像素占 3 个字节。


先讲解一下 14 字节大小的 BMP文件头,第 1~2 字节 是 魔数,在本文里面是 BM 字符串。实际上 这两个字节可以是以下的值:

  • BM:windows
  • BA:os/2 bitmap array
  • CI:os/2 color icon
  • CP:os/2 color pointer
  • IC:os/2 icon
  • PT:os/2 pointer

第 3~6 个字节是BMP文件的大小,在本文里面是 0x5EEC36 ,注意,数据类型存储是 小端存储的,看 HxD 的时候,需要从右往左看。0xEC36 缓换成 十进制 就是 6,220,854 字节,这个值跟 文件属性是可以对得上的,如下图:

第 7~10 个字节 是保留字节,以后扩展用的,这4个字节目前永远是 0 。

第 11~14 个字节 是实际的像素数据的偏移值,在本文里面是 0x36 ,没有调色板通常都是 0x36,所以从 54 字节开始,就是真正的 RGB 数据。


再来讲一下 位图信息头,位图信息头 是从 第 15 个字节开始的,前面 14 个字节 被 BMP文件头 用了。第 15 ~ 18 字节是 位图信息头 的大小,本文的 juren.bmp 的 第 15 ~ 18 字节 是 0x00000028 ,所以是 40 字节大小(包含自身),如下图:

HxD 这个软件特别棒,你只要选择内容,他就自动转成 十进制给你看。

第 19~22 字节 是 图像的宽度,单位是像素,在本文是 0x00000780 , 十进制是 1920 ,也就是 一行里面有 1920 个像素。

第 23~26 字节 是 图像的高度,单位是像素,在本文是 0x00000438 , 十进制是 1080,也就是 一列里面有 1080 个像素。高度是有符号的,可能是负数,负数的情况本文不讲解。

第 27~28 字节是 color planes 的数量 ,通常是 01 。

第 29~30 字节是 指每个像素 需要多少 位来存储,本文是 0x0018 ,十进制是 24 ,所以本文的 juren.bmp 是 RGB24 模式的,一个像素占 24 位。

第 31~32 字节是 压缩类型,本文没有压缩,所以是 0000 。

第 33~36 字节是 图像大小,不包含 BMP文件头 跟 位图信息头,其实 BMP文件头就有 总文件大小,6,220,854,减去 54 头部数据,跟 这 4 字节内容是一致的。如下图:

第 37~40 字节是 Width resolution in pixels per meter,水平分辨率,本文是 00 ,所以不管他。

第 41~43 字节是 Height resolution in pixels per meter,垂直分辨率,本文是 00 ,所以不管他。

第 44~47 字节是 颜色表中的颜色索引数,本文没有索引表,是真彩色,所以是 00 。

第 48~51 字节表示对图像显示有重要影响的颜色索引数码,本文是 00 ,代表全都重要。本文没用到索引表,不用管这个字段。


至此,juren.bmp 文件的 BMP文件头,位图信息头,已经讲解完毕,剩下的字节内容就是 真正的 RGB 值。请看下图中第一个像素的值:

上图中圈出来的像素 是 R等于00 ,B等于00,G等于00 ,所以是一个纯黑色的像素,注意,这个像素是位于 左下角的第一个像素,不是 左上角

文件中的像素排列顺序是从左下角到右上角,这个排列顺序是由 位图信息头 里面那个 高度是正数还是负数决定的。

下面我们手动修改一下 这些颜色,把黑色改成 白色,如下图:

我把 左下角 3 个像素全部改成 白色了,放大再看一下 juren.bmp ,可以看到有白色的3个像素,只是非常小,如下图:

注意,RGB24 模式中的顺序是 BGR,第一个字节是 B,第二个字节是 G, 第三个字节才是 R。

RGB24 真彩色的存储空间是很大的,juren.bmp 占了 5M 大小,从HxD 可以看到有很多重复的像素点,是一样,这些都是可以压缩的。


FFmpeg 可以自由 转换 jpeg 跟 bmp,命令如下:

ffmpeg -i juren.jpg juren.bmp
ffmpeg -i juren.bmp juren.jpg

参考文章:

1,Exploring the .BMP File Format

2,图片RGB数据格式

3,BMP文件格式详解(BMP file format)

4,A Bitmap File Analyzer


推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习]