RGB 在计算机中主要分为两大类,一种是索引形式,一种是像素形式。
目前索引形式由于表现的色彩有限,现在基本被淘汰不再使用。
在RGB像素格式中,又有RGB565、RGB555、RGB24、RGB32,多种格式。
RGB565:
一个像素用16个 bit (也就是两个字节) 表示,其中R=5、G=6、B=5,存储顺序为RGB。
R = color & 0xF800; // 取出高字节的5个bit
G = color & 0x07E0; // 取除中间的6个bit
B = color & 0x001F; // 取除低字节的5个bit
RGB555:
同样一个像素占16个 bit= 2个字节,其中R=5、G=5、B=5,然后最高位不用,存储顺序为RGB。
R = color & 0x7C00; // 取出高字节的5个bit
G = color & 0x03E0; // 取除中间的5个bit
B = color & 0x001F; // 取除低字节的5个bit
RGB24:
一个像素占24个bit,用3个字节来表示,R=8、G=8、B=8,存储顺序为BGR。
R = color & 0x0000 FF00;
G = color & 0x00FF 0000;
B = color & 0xFF00 0000;
RGB32:
一个像素占32个bit,用4个字节来表示,R=8、G=8、B=8,最后8个字节保留,存储顺序为BGR。
R = color & 0x0000 FF00;
G = color & 0x00FF 0000;
B = color & 0xFF00 0000;
A = color & 0x0000 00FF;
注意:
C/C++中默认的是小端给字节序
什么是大小端?
大端、 是指数据低位保存在内存高位地址中,而数据的高位,保存在内存的低位地址中。
小端、 是指数据的地位保存在内存低位地址中, 而数据的高位, 保存在内存的高位地址中。
YUV概述:
YUV, 是一种颜色和编码方式。常常使用在各个影响处理组件中。YUV对照片或影片进行编码时,考虑到人的感知能力,允许降低色度的带宽。
YUV分为三个分量:
通常UV一起描述影像色彩和饱和度,用来指定像素的颜色。
对于YUV图像来说,并不是每个像素都需要对应Y,U,V三个分量,根据不同的采样格式,可以每个Y都对应自己的UV分量,也可以几个 Y 共用一个UV分量。
YUV 的采样格式分为三种 YUV444、YUV422、YUV420。
YUV444
YUV4:4:4 采样意味着Y、U、V 3个分量的采样比例相同,因此生成的图像里,每个像素的三个分量信息完整,都是8 bit 也就是一个字节。
图像的像素数据为: Y0U0V0 Y1U1V1 Y2U2V2 Y3U3V3
采样的码流: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3
**为什么叫4:4:4,意思是在每4个像素就有 4个Y ,4个U,4个V **
通常一张YUV444采样的图像大小和RGB模型的图像大小是一样的。
一张1280 * 720 大小的图片,在YUV444采样时的大小为:
(1280 * 720 * 8 + 1280 * 720 * 8 + 1280 * 720 * 8)/8/1024/1024 = 2.64 MB
YUV422
YUV4:2:2 采样,每采样一个像素点都会采样其Y分量,而U、V分量就会各一个采一个,Y 和 UV 分量的采样比值为2:1。 如果说水平线上有8个像素点,那么有8个 Y ,4个U,4个V (也就是4个UV分量)。
图像的像素数据为: Y0U0V0 Y1U1V1 Y2U2V2 Y3U3V3
采样的码流: Y0 U0 Y1 V1 Y2 U2 Y3 V3
**为什么叫4:2:2,意思是在每4个像素就有 4个Y ,2个U,2个V **
一张1280 * 720 大小的图片,在YUV422采样时的大小为:
(1280 * 720 * 8 + (1280 * 720)/2 * 8 + (1280 * 720)/2 * 8)/8/1024/1024 = 1.76 MB
通过比较YUV444 和 YUV422 可以发现 YUV422 采样的图像比YUV444采样图像节省了三分之一的存储空间,在传输时占用带宽也会减少。
YUV420
YUV4:2:0 并不是说 V 分量不采样。而是说是,一行采样一个, 比如 第一行采样Y,然后U 按照2:1的比例采样,第二行同样采样Y,然后V 按照2:1 的比例采样。
图像像素数据: [Y0 U0 V0]、[Y1 U1 V1]、 [Y2 U2 V2]、 [Y3 U3 V3]
[Y5 U5 V5]、[Y6 U6 V6]、 [Y7 U7 V7] 、[Y8 U8 V8]
采样的码流: Y0 U0 Y1 Y2 U2 Y3
Y5 V5 Y6 Y7 V7 Y8
为什么叫4:2:0,意思是每4个像素中有4个Y,2个U,0个V,而下一行的四个像素中有4个Y,0个U,2个V
一张1280 * 720 大小的图片,在YUV420采样时的大小为:
(1280 * 720 * 8 + (1280 * 720)/4 * 8 + (1280 * 720)/4 * 8)/8/1024/1024 = 1.32 MB
可以看到 比起 RGB 模型图像节省了一半的存储空间,所以它也是现在主流的采样方式。
YUV 的存储格式有两大类:planar 和 packed
根据采样的格式和存储的格式不同,就有了多种YUV格式。这些格式主要是基于YUV4:2:2 和 YUV4:2:0采样。
采样格式 | planar | packed |
---|---|---|
YUV 422 | YUV422P | YUYV、UYVY |
YUV 420 | YUV420P、YUV420SP、YV12、YU12、NV12、NV21 | / |
YUV4:2:2采样格式:
YUYV
YUYV 是采用打包格式存储的,指每个像素都采用 Y 分量,但是每隔一个像素采样他的UV分量,排列顺序如下:
Y0 U0 Y1 V0 Y2 U1 Y3 V1 // Y0 Y1公用U0,V0分量。 Y2 Y3 共用 U1 V1分量
UYVY
采用打包格式存储,存储方式和YUYV相反
U0 Y0 V0 Y1 U1 Y2 V1 Y3
YUV422P
YUV422P采样格式,又叫1442,采用的是平面格式存储,先存储所有的Y分量,再存储所有的U分量,然后存储所有的V分量。
Y0 Y1 Y2 Y3 U0 U1 V0 V1
YUV4:2:0采样格式:
YUV420P 和 YUV420SP 都是基于 Planar 平面模式 进行存储的,先存储所有的 Y 分量后, YUV420P 类型就会先存储所有的 U 分量或者 V 分量,而 YUV420SP 则是按照 UV 或者 VU 的交替顺序进行存储了,具体查看看下图:
YUV420P
YUV420SP
YV12
YV12,采用的是平面格式进行存储,先存 Y 分量,再存 V 分量,最后U分量
Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
V0
U0
YU12
YU12,采用的是平面格式进行存储,先存 Y 分量,再存 U分量,最后V分量
Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
U0
V0
NV12 (ios常用)
NV12,采用的是平面格式进行存储,再 UV 进行交替存储
Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
U0 V0
NV21(android常用)
NV21,采用的是平面格式进行存储,再 VU 进行交替存储
Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
V0 U0
4 Y5 Y6 Y7
U0
V0
**NV12 (ios常用)**
NV12,采用的是平面格式进行存储,再 UV 进行交替存储
Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
U0 V0
**NV21(android常用)**
NV21,采用的是平面格式进行存储,再 VU 进行交替存储
Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
V0 U0