Android中经常使用图像格式说明

前言RGB565RGB24ARGB_8888I420 和 NV21灰阶值是什么?既然都是YUV420格式的,I420 和 NV21 到底有何区别?总结参考资料git

前言

此篇文章针对 Android 中图像处理工具 ImageUtils 的解释篇,有兴趣的童鞋能够 点击此处 了解这款开源工具。github

针对图像,存在各类各样的格式,每一个格式都不同,而在Android中,经常使用的图像格式无外乎也就几种,下面就Android中经常使用的图像格式作相关说明。web

RGB565

Android中自带的一种图像格式,这个图像格式像素排布以下图:算法

image
image

RGB565 每一个像素点都有红、绿、蓝三个原色,其中 R 原色占用 5 bitG 原色占用 6 bitB 原色占用 5 bit,也就是说一个像素点总占用 5 + 6 + 5 = 16 bitwindows

一张 640 * 480 分辨率的 RGB565 图像,其占用的内存大小为:640 * 480 * 16 / 8 = 614400 byteapp

一般在处理一个图像数据时会涉及到步长,步长计算通常为下面的公式:ide

步长 = 图像的宽 * 每一个像素点总 bit 数 / 8工具

所以,对于 640 * 480RGB565 图像而言,其步长为:640 * 16 / 8 = 1280post


RGB24

image
image

如上图,RGB24 其真正的排序是 BGR BGR ... 这种排序的,而并不是 RGB RGB ... 这种排序。编码

一样的,RGB24 每一个像素点都有蓝、红、绿三个原色 BGR 三个原色各占用 8 bit,也就是说一个像素点总占用 24 bit

一张 640 * 480 分辨率的 RGB24 图像,其占用的内存大小为:640 * 480 * 24 / 8 = 921600 byte

一样的,对于 640 * 480RGB24 图像而言,其步长为:640 * 24 / 8 = 1920


ARGB_8888

image
image

如上图,ARGB_8888 做为在Android中咱们最经常使用的一种图像格式,其实其真正的图像格式为 RGBA

ARGB_8888 除了包含 RGB 经常使用的三原色之外,还包含一个透明度 Alpha,并且一个像素点中的每一个通道各占 8 bit,一个像素点总计: 8 * 4 = 32 bit

也就是说,对于一张 640 * 480 分辨率的 ARGB_8888 图像,其占用的内存大小为:640 * 480 * 32 / 8 = 1228800 byte
而其对应的步长为:640 * 32 / 8 = 2560


I420 和 NV21

I420NV21 都是属于 YUV 格式的数据。

所谓的 YUV 格式指的是图像的颜色编码采用的是 明亮度 和 色度来指定像素的颜色,而不是一般使用的三原色来指定。
例以下图:

YUV444
YUV444

上图是一个 YUV444 的图像格式。

  • Y 表明明亮度,也即灰阶值
  • UV 表明色度,是描述影像色彩及饱和度,用于指定像素的颜色
  • 关于 YUVRGB 是如何互相转换的,您能够 参见这里

灰阶值是什么?

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
复制代码



RGB 比例基本与 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 图像采集格式主要包含 YUV422YUV420 这两种采集方式,而 I420NV21 刚好是这种数据采集方式,YUV420 数据采集大概是下面这种方式:

YUV420
YUV420

针对 YUV420 这种采用方式,有如下几个特色:

  • 每一个像素的 Y 份量必须采集
  • 采集时,每一行只扫描一种份量【或 UV】,并且采样比例为 Y : U【V】 = 2 : 1
  • 由于存在隔行采样,存在上下行像素的共用状况,所以,通常而言此类格式的图像宽和高值均为偶数

如上图,你会发现,每一个像素本来均包含 Y U V三个份量,而在进行 YUV420 采样的时候,每一个 Y 份量都进行了采集,而 UV 份量并不是每一行都采集,而是先采集一行 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

UV 份量总占用为 :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

既然都是YUV420格式的,I420 和 NV21 到底有何区别?

针对基于 YUV 4:2:0 采样的格式,主要分为两种类型:

  • YUV420P
    • YU12,即I420
    • YV12
  • YUV420SP
    • NV12
    • NV21

也就是说 I420 是属于 YUV420P 这种类型的,这种类型的格式存储有如下特色:

  • 都是基于 Planar模式【平面模式】进行存储的
  • 在存储时,先存储全部的 Y 份量,而后在存储 UV 份量
  • 若是先存储的是 U 份量,再存储的是 V 份量,则这种格式即 YU12 格式,即咱们所说的 I420 格式
  • 若是先存储的是 V 份量,再存储的是 U 份量,则这种格式即 YV12 格式

以下图,即为 一个分辨率为 8 * 4I420图像的存储格式图:

I420
I420

咱们能够把这种存储方式理解成三层,其中第一层固定存储 Y 份量,第二和第三层根据实际格式分别存储 UV(或 VU

一样的,对应的 NV21 图像格式,它是属于 YUV420SP 这种类型的,此类型的存储格式有如下特色:

  • 一样都是属于Planar模式【平面模式】进行存储的,而严格上来讲,是属于 biplanar 模式【双平面模式】
  • 在存储时,先存储全部的 Y 份量,而后再将 U V 两个份量交替连续存储
  • 若是以 UV 的循序交替存储时,则为 NV12 格式
  • 若是以 VU 的循序交替存储时,则为 NV21 格式

下图为一个分辨率为 8 * 4NV21 格式图像存储图:

NV21
NV21

至此,关于 I420NV21 这两种图像格式就介绍完了,有关更多的关于 YUV 的其余格式,可点击 此处 进行了解。

总结

  • 图像所占内存大小跟图像的实际格式及其相关
  • 每一个格式的图像都有本身对应的步长【或步幅】值,从在存储器一行像素在存储器像素的下一行的字节数
  • RGB_565 格式图像步幅为:宽 * 2
  • RGB24 格式图像步幅为:宽 * 3
  • ARGB_8888 格式图像步幅为:宽 * 4
  • I420NV21 格式图像步幅为: 宽 * 1.5
  • 图像在内存中所占用的字节大小,一般为 图像的高 * 步长
  • 对于 I420NV21 两种格式的图像,因涉及到隔行采样,上下行像素共用问题,通常此类图像的宽和高均为偶数

参考资料

相关文章
相关标签/搜索