Android中使用NDK(C/C++)对图像应用灰度效果

2023-12-26

我想使用 NDK 将灰度效果应用于图像。

为此,我在谷歌上搜索了很多,但发现了相同的结果,该结果返回的图像有点像负片(这就是我所相信的)。

我想要的是 ::

例如 ::

我有这张原图

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

我已经尝试过::

我想使用 NDK 实现此功能,因此我在 .cpp 文件中创建了一个函数

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

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

这种效果看起来有点像负片。

如果您需要我方面的任何帮助,请告诉我.. 请帮助我解决这个问题,因为我已经坚持了很多小时了。

提前谢谢了...

EDIT ::

floppy12 的建议::

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::

我对图像进行了一些简单的修改,它返回了我想要的图像,但图像失去了亮度。

这是我在本机函数中所做的更改..

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

结果(图像是灰度但失去亮度)::


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

也许使用红色分量并在灰度线计算中将其影响为绿色和蓝色

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

负图像通常是通过移动每个分量来获得的:

NegR = 255 - 灰色R

等等

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

编辑亮度: 为了获得更好的亮度,请尝试在灰度计算中添加固定量:

G += Bness;

在这里,只要您出于某种奇怪的原因从 255(黑色)变为 0(白色),Bness 似乎就应该为负值。您想要设置一个下限,使您的 grascale 值不低于 0,然后尝试:

G = max(0, G+Bness);

我推荐类似 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 );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android中使用NDK(C/C++)对图像应用灰度效果 的相关文章

随机推荐

  • Google Guice 的隐藏功能 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 django-rest-framework 中过滤 ListAPIView

    我正在使用 ListAPIView 但无法过滤结果 我的代码是 class UserPostReadView generics ListAPIView serializer class PostSerializer model serial
  • 超出 HttpClient 缓冲区大小限制

    我正在使用我的客户端获取有关存储在 Swift 对象存储中的某个文件的一些信息 该文件可以通过 REST Api 访问 在 Swift 中 指向指定对象的 HEAD 方法和 url 返回其包含在 HTML 响应 无内容 标头中的元数据 哈希
  • 捕获 QML 错误消息

    我在用着Qt createQmlObject 创建一个QML来自文件的对象 如果文件损坏 QML 会输出如下所示的消息 Qt createQmlObject failed to create object qrc graphics inli
  • Streambuilder 未收到某些快照数据

    我只是测试一些来自 GPS 的流 我可以直接插入 GPS 流 但我想暂时将其分开 所以我可以将 StreamBuilder 与我自己创建的流一起使用 这一切似乎都有效 但 Streambuilder 似乎 错过 了某些快照 这让我感到困惑
  • 如何在屏幕顶部显示通知?

    我想用jQuery 通知插件 https github com mickeyren jquery notifications 但它总是将通知栏放在页面顶部 因此 如果页面很大 则必须向上滚动到顶部才能看到通知 是否可以让通知始终显示在浏览器
  • 适用于 AMQP 的良好 Python 库 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您能推荐使用什么Python库来访问AMQP RabbitMQ 吗 根据我的研究pika似乎是首选之一
  • 通过 Uri 滑动加载本地图像。

    我正在尝试使用 Glide 从本地存储加载图像 但没有成功 Glide with mContext load pictureUri Uri of the picture transform new CircleTransform into
  • 操作栏 — 带有文本和图像的子菜单项无法正常工作

    我正在开发小型 Android 应用程序 其中使用操作栏和一些菜单项 一个菜单项包含子菜单 现在我想做的是始终显示带有文本和图标的菜单项 我按以下方式定义菜单项 menu menu
  • 关于 IIS 中最大文件上传大小的建议

    我意识到这个问题的答案取决于所使用的特定服务器 但很好奇人们是否对 ASP NET Web 表单允许的最大文件大小限制有建议 在一家印刷公司工作 希望允许图形设计师上传 我知道他们会超出我给他们的任何限制 您需要让您的用户满意 如果他们需要
  • 如何解决错误 ORA-06413:连接未打开?

    我本地环境VS2012 使用 Oracle 10g XE Dim dbConn As New OleDbConnection Dim dbComm As OleDbCommand dbConn ConnectionString Provid
  • MSI 可以与 EF Code First 一起使用吗?

    我已经在这个问题上陷入了很长一段时间 没有运气能够独自推进它 我正在尝试使用 MSI 令牌从 Azure 应用服务连接到 EF CodeFirst 托管数据库 当我使用 ARM 部署应用服务时 我生成了一个输出 确保它创建了一个服务主体 p
  • 防止 PHP 等待 mail() 函数

    在我的 Web 应用程序中 当用户对其帐户进行更改时 我调用 php mail 函数向该用户发送电子邮件通知 实施此操作后 我发现帐户更改操作需要非常长的时间 gt 20 秒 才能完成 我怀疑这是因为 PHP 等待 mail 函数发送电子邮
  • 使用 Tensorflow 训练时修改张量的值

    当我使用 Tensorflow 训练模型时 我想修改张量的值 这个张量是我的模型中的张量之一 weight tf Variable np matrix 经过一些迭代后 值weight将自动更新 我的问题是 如何修改weight非自动地 我已
  • 对象行为不正确

    我正在使用 Livewires 和 pygame 游戏中为您提供额外生命的对象之一被误认为是小行星对象 当额外生命对象与玩家碰撞时 它返回 额外生命对象没有属性 handle caught 错误消息 所以我可以提供一些帮助吗 class E
  • 使用 cert-manager 和 Nginx ingress 进行 404 质询响应

    我想得到LetsEncrypt 证书管理器 https cert manager io docs installation kubernetes 运行通过this https hub helm sh charts jetstack cert
  • 如何在Mac OS X下用C设置文件的创建日期?

    Mac OS X 存储文件创建时间 我知道如何读取它stat from
  • 如何构建 OleDbCommand 查询,以便可以从一个 .MDB 中获取表,并将其替换到另一个 .MDB 中

    我正在尝试从一个 Access 数据库文件中获取表 将它们添加到另一个结构完全相同但信息不同的 Access 数据库文件中 我需要覆盖任何现有的表 我的项目快完成了 这是我最后的砖墙 我使用名为 DatabaseHandling cs 的单
  • 进行顺序比较的优雅方法 (C++)

    假设我有一个包含多个成员变量的类 class MyClass std string a int b SomeOtherClass c some stuff public some other stuff 我想定义关系运算符 operator
  • Android中使用NDK(C/C++)对图像应用灰度效果

    我想使用 NDK 将灰度效果应用于图像 为此 我在谷歌上搜索了很多 但发现了相同的结果 该结果返回的图像有点像负片 这就是我所相信的 我想要的是 例如 我有这张原图 应用灰度效果后应该是这样的 我已经尝试过 我想使用 NDK 实现此功能 因