GrayScale Image在NDK / C ++中失去亮度

时间:2014-04-08 08:11:52

标签: android c++ image-processing android-ndk grayscale

我正在使用ARGB_8888配置传递位图。 我能够将灰度效果应用于图像,但在应用之后,我将失去其亮度。

我搜索了很多内容,但发现了与我相同的实现方式。

这是我的本土文章::

JNIEXPORT void JNICALL Java_com_example_ndksampleproject_MainActivity_jniConvertToGray(JNIEnv * env, jobject  obj, jobject bitmapcolor,jobject bitmapgray)
{
    AndroidBitmapInfo  infocolor;
    void*              pixelscolor;
    AndroidBitmapInfo  infogray;
    void*              pixelsgray;
    int                ret;
    int             y;
    int             x;

    LOGI("convertToGray");
    if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }

    if ((ret = AndroidBitmap_getInfo(env, bitmapgray, &infogray)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }

    LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infocolor.width,infocolor.height,infocolor.stride,infocolor.format,infocolor.flags);
    if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGE("Bitmap format is not RGBA_8888 !");
        return;
    }

    LOGI("gray image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infogray.width,infogray.height,infogray.stride,infogray.format,infogray.flags);
    if (infogray.format != ANDROID_BITMAP_FORMAT_A_8) {
        LOGE("Bitmap format is not A_8 !");
        return;
    }

    if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    if ((ret = AndroidBitmap_lockPixels(env, bitmapgray, &pixelsgray)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    LOGI("unlocking pixels height = %d",infocolor.height);

    // modify pixels with image processing algorithm

    for (y=0;y<infocolor.height;y++) {
        argb * line = (argb *) pixelscolor;
        uint8_t * grayline = (uint8_t *) pixelsgray;
        for (x=0;x<infocolor.width;x++) {
            grayline[x] = ((255-0.3 * line[x].red) + (255-0.59 * line[x].green) + (255-0.11*line[x].blue))/3;
        }

        pixelscolor = (char *)pixelscolor + infocolor.stride;
        pixelsgray = (char *) pixelsgray + infogray.stride;
    }

    LOGI("unlocking pixels");
    AndroidBitmap_unlockPixels(env, bitmapcolor);
    AndroidBitmap_unlockPixels(env, bitmapgray);
}

结果::

enter image description here

如果您需要我的任何东西,请告诉我。 请帮助我解决这个问题,因为我从很多个小时就陷入困境。 非常感谢提前!!!

编辑::

应用Mark Setchell的建议::

enter image description here

EDITED

如果你反转上面的图片,你会得到这个 - 这对我来说是正确的:

enter image description here

2 个答案:

答案 0 :(得分:2)

不要在计算grayline [x]的行上除以3。您的答案已正确加权,因为0.3 + 0.59 + 0.11 = 1

grayline[x] = (255-0.3 * line[x].red) + (255-0.59 * line[x].green) + (255-0.11*line[x].blue);

答案 1 :(得分:2)

您当前的代码存在两个问题。

1)如其他人所述,不要将最终结果除以3。如果您使用平均方法计算灰度(例如灰色=(R + G + B)/ 3),则必须进行除法。对于您正在使用的国际电联转换公式,不需要进行额外划分,因为小数金额已经合计为1。

2)发生反转是因为您从255中减去每个颜色值。没有必要这样做。

您当前公式的正确灰度转换代码为:

grayline[x] = ((0.3 * line[x].red) + (0.59 * line[x].green) + (0.11*line[x].blue));