RGB到YUV420平面和半平面?

时间:2016-05-20 22:13:24

标签: java android rgb mediacodec yuv

在Android中,我有一个byte[]的个体r,g,b,这些颜色构成了图像的像素。

在使用Android的MediaCodec和MediaMuxer创建这些图像的MP4之前,我需要将这些颜色转换为 YUV420平面或半平面(取决于设备)。

我目前正在测试我的Nexus 10,它报告它使用COLOR_FormatYUV420Planar

以下是我将RGB转换为YUV420 平面的代码:

private void convertRGBAtoYUV420P(byte[] rgba, byte[] yuv, int width, int height)
{
    final int frameSize = width * height;
    final int chromasize = frameSize / 4;

    int yIndex = 0;
    int uIndex = frameSize;
    int vIndex = frameSize + chromasize;

    int R, G, B, Y, U, V;
    int index = 0;

    int rgbaIndex = 0;

    for (int j = 0; j < height; j++)
    {
        for (int i = 0; i < width; i++)
        {
            R = rgba[rgbaIndex++] + 128; // My rgba bytes are -128 to 127
            G = rgba[rgbaIndex++] + 128;
            B = rgba[rgbaIndex++] + 128;
            rgbaIndex++; // skip A

            Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
            U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
            V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

            yuv[yIndex++] = (byte)clamp(Y);

            if (j % 2 == 0 && index % 2 == 0)
            {
                yuv[uIndex++] = (byte)clamp(U);
                yuv[vIndex++] = (byte)clamp(V);
            }

            index++;
        }
    }
}

我从this blog找到了这段代码。

它有效,只是颜色不正确。白色是灰色的,所有其他颜色都是错的。无法弄清楚上面的代码有什么问题,但我觉得这可能与我的r,g,b,一个字节在-128到127范围内的事实有关,但我试着通过向它们添加128来纠正它。

第二个问题,当我需要从RGB转换为YUV420 半平面时,上述代码将如何变化?

1 个答案:

答案 0 :(得分:3)

这样就可以回答这个问题。

问题是在字节值中添加128并不能恢复它的原始值。

因为颜色空间定义在0到255之间的值。它们不是简单地向下移向负数,以使其适合有符号的字节。所有较高的颜色值(> 127)都被编码为适合有符号的字节,范围从-128到-1。

为了将值恢复到您想要的值,您需要将& 0xff掩码应用于每个字节值。