YUV_420_888(字节)格式

时间:2018-07-18 10:39:21

标签: android arrays yuv

我在Android上以YUV_420_888(YCbCr)格式捕获了图像。

图像尺寸为 4032 X 3024 ,我从 ImageReader 获得了三个平面。

  

Y为12192768字节
  具有6096383字节的U
  V,带有6096383字节

我的理解是,对于 Y 中的每个像素,在 U / V 平面中都有一个比例为2:1的值(2个像素Y对应一个像素U / V)。

但是进行数学运算 12192768/2 时,在 U / V 平面中缺少一个字节。

为什么缺少一个字节?对于Android camera2 YUV_420_888。 Y U / V 之间的关系如何。

2 个答案:

答案 0 :(得分:3)

好的,让我们再试一次。最初,我问是否有人找到答案,因为我也在寻找解决方案。最后,尽管我已经能够弄清楚我们对这个问题的答案:

答案在于图像获取格式。 Android一直默认为NV21格式,即V字节,然后是Y平面之后的U字节交织平面。 NV12是备用字符,其U字节位于V字节之前(请参见:How to render Android's YUV-NV21 camera image on the background in libgdx with OpenGLES 2.0 in real-time?

然后,由ImageReader返回的Image对象创建一个ByteBuffer,它直接访问此内存位置。在ByteBuffer上调用isDirect()验证了这一点。您也可以通过修改vBuffer(getPlane()[2])索引1来查看此信息。由于vBuffer的索引1指向uBuffer索引0的相同内存位置,因此uBuffer.get(0)相同。

因此,UV平面(NV21的VU平面)等于Y平面/ 2 = 长度(如上例中所述6096384)。如果您从第一个V(VU-plane [0])开始并计数到最后一个V(VU-plane [length-1]),它将减少一个,因为此平面中的最后一个字节为U。直到VU-plane [length]为止,U字节在VU-plane的索引1处。

这是一张希望在视觉上解释上述措辞的图片: enter image description here

这全部基于以下事实:图像是以NV21格式而不是NV12或Y12捕获的。这是另一个可供参考的视觉效果(https://www.twblogs.net/a/5d7ede57bd9eee541c3480f3

答案 1 :(得分:0)

您是否考虑到每个平面的行距和像素跨度? 3个平面的行和像素之间可能会有填充,这会更改总计数。