帆布油漆 - 红色和绿色倒置

问题描述 投票:0回答:1

我有一个应用程序捕获正在使用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设置为红色并将任何线条/矩形绘制为红色(以便在绘制时它们显示为蓝色) - 但我宁愿理解为什么会发生这种情况。我错过了一些明显的东西吗

java android canvas paint
1个回答
0
投票

通过捕获帧,应用水印然后将其保存为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

© www.soinside.com 2019 - 2024. All rights reserved.