使用NDK(C / C ++)中的Andr​​oid应用灰度效果图片 [英] Apply grayscale effect to Image using NDK(C/C++) in Android

查看:215
本文介绍了使用NDK(C / C ++)中的Andr​​oid应用灰度效果图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用NDK的灰阶效果应用到图像。

I want to apply the grayscale effect to image using NDK.

有关,我用Google搜索了很多,但发现了同样的结果,返回的形象有点像负(这是我相信)。

For that i have googled a lot but found the same result which returns the image in somewhat like negative(this is what i believe).

我想::

例如::

我有这样的原始图像

应用灰度效果后,它应该是这样的:

After applying the grayscale effect it should be like this ::

我曾尝试::

我想实现使用NDK这一功能,所以,我在.cpp文件中创建一个功能

I want to achieve this functionality using NDK,so that i have created one function in .cpp file

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] = 0.3 * line[x].red + 0.59 * line[x].green + 0.11*line[x].blue;
        }

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

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

上面的函数返回了我这样的结果::

The above function return me the result like this ::

这效果看起来有点像形象负面的。

This effect looks like something like negative of image.

让我知道如果u需要从我身边任何东西.. 请帮我解决这个问题,因为我一直坚持到这个从几个小时。

Let me know if u need anything from my side.. Please help me to solve this issue as i have stuck into this from many hours.

在提前非常感谢......

Many Thanks in Advance...

修改::

floppy12的建议::

floppy12's Suggestion ::

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;
    }

输出::

编辑2 ::

我已经做了一些简单的修改图像,并返回我要什么,但图像失去其亮度的图像。

I have made the some simple modification to the image and it returns me the image what i wanted but the image lost its brightness.

这是我在本机的功能所做的更改。

This is the changes that i have made in native function..

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;
    }

结果(图像grayscaled但失去它的亮度)::

推荐答案

要获得在灰度图像中,每个像素应具有相同量的红,绿和蓝

To obtain an image in grayscale, each pixel should have the same amount of red, green and blue

也许使用的红色成分,它影响到绿色和蓝色的grayline计算

Maybe use the red component and affect it to both green and blue in your grayline computation

,或使用式(R + G + B)/ 3 =灰色

or use the formula (R+G+B)/3 = Gray

负面形象通常是由移动每个组件获得:

Negative images are normally obtained by by shifting each component :

NEGR = 255 - grayR

NegR = 255 - grayR

所以,你可以尝试计算grayscal [X] =(255 - 0.3 *线[X])+ ...

So you could try to compute grayscal[x] = (255 - 0.3*line[x]) + ...

编辑亮度: 为了获得更好的亮度,尽量以固定的金额添加到您的灰度计算:

Edit for brightness: To obtain better brightness, try to add a fixed amount to your grayscale computation:

G += Bness;

这似乎Bness应该是否定的,只要你是从255(黑色)将0(白)一些奇怪的原因。你想提出一个跌停下0不会去为你grascale值,然后尝试:

Here it seems that Bness should be negative as long as you are going from 255(black) to 0(white) for some strange reason. You want to put a down limit to not go under 0 for your grascale value, then try :

G = max(0, G+Bness);

我建议像Bness = -25

I recommend something like Bness = -25

编辑实现亮度:

// Declare a global variable for your brightness - outside your class
static uint8_t bness = -25;

// In your grayscale computation function
for y...
 for x...
  grayscale[x] = ( (255-0.3*line[x].red) + ..... ) /3 ;
  int16_t gBright = grayscale[x] + bness;
  grayscale[x] = MAX( 0, gBright );

这篇关于使用NDK(C / C ++)中的Andr​​oid应用灰度效果图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆