Холст для краски - перевернутые красные и зеленые - PullRequest
0 голосов
/ 13 января 2019

У меня есть приложение, которое захватывает кадр из видео, которое записывается с использованием ImageAvailableListener, и рисует водяной знак в верхней части кадра. Водяной знак сохраняется в виде файла PNG и имеет синий цвет. Однако, когда я рисую водяной знак на захваченном кадре, он становится красным. Точно так же любые прямоугольники или линии, которые я рисую на холсте, используя синий цвет, выглядят красными, но захваченное изображение сохраняет свои цвета очень хорошо. Вот код:

//Capture the image
final Image img = reader.acquireLatestImage();
if (img == null)
{
   totalImages--;
   return;
}

//Convert from Bytes into bitmap
byte[] data = getBytesFromYuv(img);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bitmap = Bitmap.createBitmap(imgWidth,imgHeight,conf);
ByteArrayOutputStream out = new ByteArrayOutputStream();
YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, imgWidth, imgHeight, null);
data = null;
yuvImage.compressToJpeg(new Rect(0, 0, imgWidth, imgHeight), JPEG_QUALITY, out);
byte[] imageBytes = out.toByteArray();
bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);

//Release the image
img.close();

//Create mutable bitmap and initiate canvas & paint
Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
Paint p = new Paint();

//Set color to blue
p.setColor(Color.argb(255,0,0,255)); //Set color to BLUE

//...draw watermark, lines or rectangles here...
//Anything drawn using canvas/paint appears with blues/reds inverted
//but underlying frame captured retains its colors just fine.

После этого кода я использую некоторые другие функции для кодирования кадра с водяным знаком в YUV420 для других целей - я думал, что проблема может заключаться в этой функции, но учитывая, что захваченный видеокадр сохраняет свой цвет очень хорошо (только наложенный водяной знак ), я пришел к выводу, что это не проблема, и не включил этот код.

Очевидное быстрое решение для моей проблемы - сделать мой водяной знак PNG красным и нарисовать все линии / прямоугольники красным (чтобы они отображались синим цветом при рисовании) - но я бы лучше понял, почему это происходит. Я что-то упускаю из виду?

1 Ответ

0 голосов
/ 12 февраля 2019

Я обнаружил, в чем заключается проблема, захватив кадр, применив водяной знак, а затем сохранив его как изображение JPEG (перед отправкой в ​​видеокодер). Цвета на изображении выглядели просто отлично, поэтому я знал, что странные цвета происходили после процесса кодирования видео.

В конце концов, моя проблема возникла из-за недостатка знаний о цветовых форматах. Для видео используются разные цветовые форматы, чем для растровых изображений. Мой видеокодек использует формат YUV420, где в качестве моего растрового изображения используется ARGB_8888. Решением моей проблемы было применение ColorMatrix к моему объекту Paint, чтобы учесть изменения цвета, которые произойдут во время процесса кодирования (то есть инвертирование красного и зеленого). Этот код вставляется до того, как я начну рисовать поверх захваченного кадра.

//Initiate color filter
ColorMatrix cm = new ColorMatrix();
float[] matrix = {
    0, 0, 1, 0, 0, //Red (Grabbing blue values)
    0, 1, 0, 0, 0, //Green 
    1, 0, 0, 0, 0, //Blue (Grabbing red values)
    0, 0, 0, 1, 0 //Alpha 
};
cm.set(matrix);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);

//Set color filter
p.setColorFilter(f);

Для получения дополнительной информации о ColorMatrix, обратитесь к: Android: ColorMatrix

...