前言RGB565RGB24ARGB_8888I420 和 NV21灰阶值是什么?既然都是YUV420格式的,I420 和 NV21 到底有何区别?总结参考资料git
此篇文章针对
Android
中图像处理工具 ImageUtils 的解释篇,有兴趣的童鞋能够 点击此处 了解这款开源工具。github
针对图像,存在各类各样的格式,每一个格式都不同,而在Android中,经常使用的图像格式无外乎也就几种,下面就Android中经常使用的图像格式作相关说明。web
Android中自带的一种图像格式,这个图像格式像素排布以下图:算法
RGB565
每一个像素点都有红、绿、蓝三个原色,其中 R
原色占用 5 bit
,G
原色占用 6 bit
,B
原色占用 5 bit
,也就是说一个像素点总占用 5 + 6 + 5 = 16 bit
。windows
一张 640 * 480
分辨率的 RGB565
图像,其占用的内存大小为:640 * 480 * 16 / 8 = 614400 byte
app
一般在处理一个图像数据时会涉及到步长,步长计算通常为下面的公式:ide
步长 = 图像的宽 * 每一个像素点总 bit 数 / 8工具
所以,对于 640 * 480
的 RGB565
图像而言,其步长为:640 * 16 / 8 = 1280
post
如上图,RGB24
其真正的排序是 BGR BGR ...
这种排序的,而并不是 RGB RGB ...
这种排序。编码
一样的,RGB24
每一个像素点都有蓝、红、绿三个原色 B
、G
、R
三个原色各占用 8 bit
,也就是说一个像素点总占用 24 bit
。
一张 640 * 480
分辨率的 RGB24
图像,其占用的内存大小为:640 * 480 * 24 / 8 = 921600 byte
。
一样的,对于 640 * 480
的 RGB24
图像而言,其步长为:640 * 24 / 8 = 1920
如上图,ARGB_8888
做为在Android中咱们最经常使用的一种图像格式,其实其真正的图像格式为 RGBA
。
ARGB_8888
除了包含 R
、G
、B
经常使用的三原色之外,还包含一个透明度 Alpha
,并且一个像素点中的每一个通道各占 8 bit
,一个像素点总计: 8 * 4 = 32 bit
。
也就是说,对于一张 640 * 480
分辨率的 ARGB_8888
图像,其占用的内存大小为:640 * 480 * 32 / 8 = 1228800 byte
。
而其对应的步长为:640 * 32 / 8 = 2560
I420
和 NV21
都是属于 YUV
格式的数据。
所谓的 YUV
格式指的是图像的颜色编码采用的是 明亮度 和 色度来指定像素的颜色,而不是一般使用的三原色来指定。
例以下图:
上图是一个 YUV444
的图像格式。
Y
表明明亮度,也即灰阶值UV
表明色度,是描述影像色彩及饱和度,用于指定像素的颜色YUV
与 RGB
是如何互相转换的,您能够 参见这里当
R = B = G
时候,像素点的颜色就呈现黑白色调,这种像素点拼接起来的图像呈现为灰度图,R = B = G
的通道值就是灰阶。
一般状况下彩色像素点转灰阶值通常采用大体于R:G:B=3:6:1
的算法计算灰阶值,实际上RGB
转换成YUV
时,Y
份量的计算公式为:Y = 0.299 * R + 0.587 * G + 0.114 * B
复制代码
其R
、G
、B
比例基本与3 : 6 : 1
吻合【具体的可 点击参考此处 】。
继续说回 YUV,针对 YUV444
这种格式,其采样比例为 Y
: U
: V
= 4 : 4 : 4
,也即 1 : 1 : 1
。
例如上图,其采样流是这样的:
Y1
U1
V1
Y2
U2
V2
Y3
U3
V3
Y4
U4
V4
Y5
U5
V5
...
也就是说采样时候每一个像素的 Y
U
V
三个份量都是完整的,而在一个像素点中,一个完整的份量占用 8 bit
大小,
所以针对一个 640 * 480
大小的 YUV444
的图像,其真实的占用大小为:
640 * 480 * 8 * 3 = 921600 bit
跟 RGB24
占用的大小是一致的;一样的针对 YUV444
,其图像的步长同样跟 RGB24
同样,为 640 * 3 = 1920
。
针对这种彻底采样的 YUV
格式,并无给图像进行压缩,所以业界也不多使用 YUV444
这种格式对图像进程存储。
实际上,目前使用最多的 YUV
图像采集格式主要包含 YUV422
和 YUV420
这两种采集方式,而 I420
和 NV21
刚好是这种数据采集方式,YUV420
数据采集大概是下面这种方式:
针对 YUV420
这种采用方式,有如下几个特色:
Y
份量必须采集U
或 V
】,并且采样比例为 Y
: U【V】
= 2
: 1
如上图,你会发现,每一个像素本来均包含 Y
U
V
三个份量,而在进行 YUV420
采样的时候,每一个 Y
份量都进行了采集,而 U
和 V
份量并不是每一行都采集,而是先采集一行 U
份量在采集一行 V
份量,并且是每隔一个像素点采集一次的。上图第一行 对 Y
份量都采集了,而 U
份量只采集了 Y
份量的一半,V
份量没有采集;到第二行,Y
份量仍是所有采集,此时 V
份量采集了,采集的数量是 Y
份量的一半,U
份量未采集。
也就是说其采样流是这样的:
Y1
U1
Y2
Y3
U3
Y4
Y5
V5
Y6
Y7
V7
Y8
Y9
U9
Y10
Y11
U11
Y12
Y13
V13
Y14
Y15
V15
Y16
同时映射成的像素点如上图蓝色虚线框中的方式进行映射,也即下面这种:
[Y1 U1 V5]
[Y2 U1 V5]
[Y3 U3 V7]
[Y4 U3 V7]
[Y5 U1 V5]
[Y6 U1 V5]
[Y7 U3 V7]
[Y8 U3 V7]
[Y9 U9 V13]
[Y10 U9 V13]
[Y11 U11 V15]
[Y12 U11 V15]
[Y13 U9 V13]
[Y14 U9 V13]
[Y15 U11 V15]
[Y16 U11 V15]
针对 YUV420
这种采样的图像,你会发现这种方式对图片作了必定的压缩,咱们能够根据上面的方式计算,
对于一个 640 * 480
大小的图像,其占用的内存为:Y
份量:640 * 480 * 8 = 2457600 bit
U
和 V
份量总占用为 :640 * 480 * 0.5 * 8 = 1228800 bit
所以总占用内存大小为:640 * 480 * 8 + 640 * 480 * 0.5 * 8 = 3686400 bit = 460800 byte
同时能够计算出对于的 YUV420
格式的大小为 640 * 480
图像的步长为:640 + 0.5 * 640 = 960
针对基于 YUV 4:2:0
采样的格式,主要分为两种类型:
YUV420P
YUV420SP
也就是说 I420
是属于 YUV420P
这种类型的,这种类型的格式存储有如下特色:
Planar
模式【平面模式】进行存储的Y
份量,而后在存储 U
或 V
份量U
份量,再存储的是 V
份量,则这种格式即 YU12
格式,即咱们所说的 I420
格式 V
份量,再存储的是 U
份量,则这种格式即 YV12
格式 以下图,即为 一个分辨率为 8 * 4
的I420
图像的存储格式图:
咱们能够把这种存储方式理解成三层,其中第一层固定存储 Y
份量,第二和第三层根据实际格式分别存储 U
和 V
(或 V
和 U
)
一样的,对应的 NV21
图像格式,它是属于 YUV420SP
这种类型的,此类型的存储格式有如下特色:
Planar
模式【平面模式】进行存储的,而严格上来讲,是属于 biplanar
模式【双平面模式】Y
份量,而后再将 U
V
两个份量交替连续存储U
和 V
的循序交替存储时,则为 NV12
格式V
和 U
的循序交替存储时,则为 NV21
格式下图为一个分辨率为 8 * 4
的 NV21
格式图像存储图:
至此,关于 I420
和 NV21
这两种图像格式就介绍完了,有关更多的关于 YUV
的其余格式,可点击 此处 进行了解。