我在 Android 上以 YUV_420_888 格式 (YCbCr) 捕获图像。
图片尺寸为 4032 X 3024 我从 得到三架飞机图片阅读器 .
Y with 12192768 bytes
U with 6096383 bytes
V with 6096383 bytes
我的理解是对于 中的每个像素是 中有对应的值紫外线 具有 2:1 比例的平面(2 个像素 Y 对应于 1 个像素 U/V)。
但是做数学 12192768/2 中缺少一个字节紫外线 飞机。
为什么缺少一个字节? 之间的关系如何?是 和 紫外线 安卓版相机2 YUV_420_888。
最佳答案
好的,让我们再试一次。最初我问是否有人找到了答案,因为我也在寻找解决方案。最后,虽然我已经能够弄清楚我们对这个问题的答案:
答案在于图像采集格式。 Android 直到默认为 NV21 格式,这意味着一个 V 字节后跟一个 U 字节交织平面在 Y 平面之后。 NV12 是在 V 字节之前具有 U 字节的替代(参见: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。同样第一个U 字节位于 VU-plane 的索引 1 处,直到 VU-plane[length]。
这是一张希望在视觉上解释上述措辞的图像:
这一切都基于这样一个事实,即图像是以 NV21 格式而不是 NV12 或 Y12 格式捕获的。这是另一个很好的视觉引用(https://www.twblogs.net/a/5d7ede57bd9eee541c3480f3)
关于android - YUV_420_888(字节)格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51399908/