RGB в YUV420 Планарный и Полупланарный?
В Android у меня есть byte[]
отдельных R, G, B, цвета, которые составляют пиксели изображения.
Мне нужно преобразовать эти цвета в YUV420 планарный или полуплоскостной (в зависимости от устройства), прежде чем я смогу использовать Android MediaCodec и MediaMuxer для создания MP4 из этих изображений.
В настоящее время я тестирую свой Nexus 10, который сообщает, что он использует COLOR_FormatYUV420Planar
,
Вот код, который я должен конвертировать RGB в YUV420 planar:
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++;
}
}
}
Я нашел этот код из этого блога.
Это работает, просто цвет не правильный. Белый это серый, а все остальные цвета просто неправильные. Не могу понять, что не так в приведенном выше коде, но я чувствую, что это может быть связано с тем фактом, что мои байты r, g, b, a находятся в диапазоне от -128 до 127, но я пытаюсь исправить это, добавив к ним 128.
Второй вопрос, как изменится приведенный выше код, когда мне нужно будет вместо этого конвертировать из RGB в YUV420 полуплоскостной?
1 ответ
Просто так есть ответ на этот вопрос.
Проблема в том, что добавление 128 к значениям байта не восстанавливает его первоначальное значение.
Поскольку цветовое пространство определяется значениями от 0 до 255. Они не просто смещаются вниз к отрицательному числу, чтобы оно помещалось в подписанный байт. Все более высокие значения для цветов (> 127) кодируются, чтобы уместиться в байте со знаком, в диапазоне от -128 до -1.
Для того, чтобы восстановить значение до того, что вы хотите, вам нужно применить & 0xff
Маска для каждого значения байта.