当前位置: 首页 > 知识库问答 >
问题:

在Android中红色和蓝色是互换的

施彦
2023-03-14

做一个Sylvain Ratabouil Android NDK(第二版)的例子,从相机获得图像预览,并对其进行本地处理,从YUV转换为RGB,并对其应用滤色器。

代码非常简单,问题发生在传递给这个函数的过滤器中:

public native void decode(Bitmap target, byte[] source, int filter);

目标是对ImageView的引用
源是帧预览数据
过滤器是彩色过滤器

decode(mImageRed,   data, 0xFFFF0000);
decode(mImageGreen, data, 0xFF00FF00);
decode(mImageBlue,  data, 0xFF0000FF);
decode(mImageRed,   data, 0xFF0000FF);
decode(mImageGreen, data, 0xFF00FF00);
decode(mImageBlue,  data, 0xFFFF0000);

*为红色图像用0xFFFF0000改变0xFF0000FF滤镜,反之亦然。

在本机部分中,它所做的只是用位运算符和(&)应用筛选器:

bitmapContent[yIndex] &= pFilter;

有人知道颜色交换的时候吗?因为我认为0xFFF0000是红色的,而不是0xFF0000FF。

void JNICALL
decode(JNIEnv *pEnv, jclass pClass, jobject pTarget, jbyteArray pSource, jint pFilter) {

    // Retrieves bitmap information and locks it for drawing.
    AndroidBitmapInfo bitmapInfo;
    uint32_t *bitmapContent;

    if (AndroidBitmap_getInfo(pEnv, pTarget, &bitmapInfo) < 0)
        abort();

    if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
        abort();

    if (AndroidBitmap_lockPixels(pEnv, pTarget, (void **) &bitmapContent) < 0)
        abort();

    // Accesses source array data.
    jbyte *source = (*pEnv)->GetPrimitiveArrayCritical(pEnv, pSource, 0);
    if (source == NULL)
        abort();

    int32_t frameSize = bitmapInfo.width * bitmapInfo.height;
    int32_t yIndex, uvIndex, x, y;
    int32_t colorY, colorU, colorV;
    int32_t colorR, colorG, colorB;
    int32_t y1192;

    // Processes each pixel and converts YUV to RGB color.
    // Algorithm originates from the Ketai open source project.
    // See http://ketai.googlecode.com/.
    for (y = 0, yIndex = 0; y < bitmapInfo.height; y++) {
        colorU = 0;
        colorV = 0;
        // Y is divided by 2 because UVs are subsampled vertically.
        // This means that two consecutives iterations refer to the
        // same UV line (e.g when Y=0 and Y=1).
        uvIndex = frameSize + (y >> 1) * bitmapInfo.width;
        for (x = 0; x < bitmapInfo.width; x++, yIndex++) {
            // Retrieves YUV components. UVs are subsampled
            // horizontally too, hence %2 (1 UV for 2 Y).
            colorY = max(toInt(source[yIndex]) - 16, 0);
            if (!(x % 2)) {
                colorV = toInt(source[uvIndex++]) - 128;
                colorU = toInt(source[uvIndex++]) - 128;
            }
            // Computes R, G and B from Y, U and V.
            y1192 = 1192 * colorY;
            colorR = (y1192 + 1634 * colorV);
            colorG = (y1192 - 833 * colorV - 400 * colorU);
            colorB = (y1192 + 2066 * colorU);

            colorR = clamp(colorR, 0, 262143);
            colorG = clamp(colorG, 0, 262143);
            colorB = clamp(colorB, 0, 262143);

            // Combines R, G, B and A into the final pixel color.
            bitmapContent[yIndex] = color(colorR, colorG, colorB);
            bitmapContent[yIndex] &= pFilter;
        }
    }

    (*pEnv)->ReleasePrimitiveArrayCritical(pEnv, pSource, source, 0);
    if (AndroidBitmap_unlockPixels(pEnv, pTarget) < 0)
        abort();
}
mImageR = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
mImageG = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
mImageB = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
mImageViewR.setImageBitmap(mImageR);
mImageViewG.setImageBitmap(mImageG);
mImageViewB.setImageBitmap(mImageB);

共有1个答案

齐俊贤
2023-03-14

您的decode()函数是为NV21视频格式硬编码的,但相机可以为YV12设置。这可能是颜色“交换”的原因。请注意,对于某些分辨率,YV12可以有行填充(NV21保证“完全包装”)。

在一次运行中生成三个平面可能要快得多,但目前还不清楚整数运算是否真的比现代CPU上的浮点运算快。

如果分辨率很高,并且处理时间很重要,可以考虑使用RenderScript。

 类似资料:
  • 问题内容: 该方法返回单个int。如何分别获得红色,绿色和蓝色作为0到255之间的值? 问题答案: Java的Color类可以进行转换:

  • 有没有一种方法可以轻松地将给定的十六进制颜色代码分配给更一般的类别(红色、绿色、蓝色、黄色、橙色、粉色、黑色、白色、灰色...)? 比如- 编辑:甚至与adobe photoshop类似,找到最接近的网络安全颜色,这样可以将颜色数量减少到256种,这已经是一个很好的解决方案了!

  • 在使用设计支持库中的TextInputLayout时,是否可以将提示中的星号设置为红色?我尝试了很多东西,但星号的颜色一直在变化,从红色到主题色,当它改变为浮动标签。当我被困在这里时,请帮帮我。谢谢

  • 你好啊。我已经从web(KryoNet)导入了一个外部库到我的Android Studio中。现在我在这个库的代码中(在UdpConnection文件中)做了一个更改。我应该以某种方式重新同步这些更改吗?我不知道这个感叹号和深蓝色是什么意思。更改不是保存了吗?

  • 我正在尝试使用IBMCloud中的红色节点。我在平台上有一个Lite帐户,但目前没有安装任何应用程序。当我在安装后尝试部署它时,我得到: 我用了128来分配内存。在日志中,我得到这个错误消息: 如何在不创建其他帐户的情况下更正此错误?

  • threejs 柱状图如何实现渐变色,比如从红色变成蓝色