Java RGB到YUV420平面和半平面?

Java RGB到YUV420平面和半平面?,java,android,rgb,android-mediacodec,yuv,Java,Android,Rgb,Android Mediacodec,Yuv,在安卓系统中,我有一个字节[],分别是r、g、b,一种构成图像像素的颜色 我需要将这些颜色转换为YUV420平面或半平面(取决于设备),然后才能使用Android的MediaCodec和MediaMuxer创建这些图像的MP4 我目前正在测试我的Nexus 10,它报告说它使用了颜色_formatyuv420平面 下面是我必须将RGB转换为YUV420平面的代码: private void convertRGBAtoYUV420P(byte[] rgba, byte[] yuv, int wid

在安卓系统中,我有一个
字节[]
,分别是r、g、b,一种构成图像像素的颜色

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

我目前正在测试我的Nexus 10,它报告说它使用了
颜色_formatyuv420平面

下面是我必须将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++;
        }
    }
}
private void convertRGBAtoYUV420P(字节[]rgba,字节[]yuv,整数宽度,整数高度)
{
最终整数帧大小=宽度*高度;
最终int-chromasize=帧大小/4;
int-yIndex=0;
int uIndex=帧大小;
int-vIndex=帧大小+色度;
int R,G,B,Y,U,V;
int指数=0;
int rgbaIndex=0;
对于(int j=0;j>8)+16;
U=(-38*R-74*G+112*B+128)>>8+128;
V=((112*R-94*G-18*B+128)>>8)+128;
yuv[yIndex++]=(字节)钳位(Y);
如果(j%2==0&&index%2==0)
{
yuv[uIndex++]=(字节)钳位(U);
yuv[vIndex++]=(字节)钳位(V);
}
索引++;
}
}
}
我从中找到了这个代码


它能用,只是颜色不对。白色是灰色的,所有其他颜色都是错误的。我不太清楚上面代码中的错误,但我觉得这可能与我的r,g,b,a字节在-128到127之间有关,但我试图通过向它们添加128来纠正这一点


第二个问题,当我需要将RGB转换为YUV420半平面时,上面的代码会如何更改?

这就是这个问题的答案

问题是向字节值添加128并不能恢复其原始值

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


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

也许不需要向字节值添加128,而是执行
&0xff
以获得介于
0
255
之间的值。通过添加128,基本上减少了可用颜色的一半。如果红色值为-64(实际上是192),则得到的是64。或者,如果你的值为-1(这将是一种颜色的最大值[255]),加上128,你得到的是127。@Zymus,你完全正确。我并不是真的在思考,只是假设范围向下移动了128,所以只要加上128,它就会像正常情况一样变为0-255。0xff面具成功了,谢谢!“它可以工作,只是颜色不正确。白色是灰色,而所有其他颜色都是错误的。”:没错!它起作用了fine@gpasch我明白这听起来有多么愚蠢,但我的意思是,我可以看到图像,辨认出物体等等,所以像素“位置”数据写得正确,只是颜色数据不正确。你的另一个选择是给mediacodec提供一个表面。在曲面上绘制RGB像素,让硬件进行YUV转换。诀窍在于,您必须使用GLES来完成此操作——此()不支持画布渲染。