最近想练习一下NDK,基于我接下来的目标是多媒体,多以想多点学习一下关于滤镜的知识,黑白滤镜是最简单的了。

这里实现的是将一张彩色图片转成黑白图片,是黑白滤镜的基础!

直接上码:

// java 代码
public void gray(View view) {Bitmap source = BitmapFactory.decodeResource(getResources(), R.drawable.time);Bitmap target = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);BitmapTools.gray(source, target);targetView.setImageBitmap(target);
}
// c 代码
#include <jni.h>
#include <android/bitmap.h>
#include <android/log.h>#define TAG "bitmap-lib"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG ,__VA_ARGS__)extern "C"
JNIEXPORT void JNICALL
Java_com_johan_ndk_BitmapTools_gray(JNIEnv *env, jobject obj, jobject source, jobject target) {int result;// 获取源Bitmap相关信息:宽、高等AndroidBitmapInfo sourceInfo;result = AndroidBitmap_getInfo(env, source, &sourceInfo);if (result < 0) {LOGE("get bitmap info error : %d", result);return;}// 获取源Bitmap像素数据 这里用的是32位的int类型 argb每个8位uint32_t *sourceData;result = AndroidBitmap_lockPixels(env, source, (void**) &sourceData);if (result < 0) {LOGE("bitmap lock pixels error : %d", result);return;}// 锁定Bitmap // 并获取目标Bitmap像素数据 // 注意:传进来的Bitmap只是一张空的Bitmapuint32_t *targetData;result = AndroidBitmap_lockPixels(env, target, (void**) &targetData);if (result < 0) {LOGE("bitmap lock pixels error : %d", result);return;}// 遍历各个像素点int color;int alpha = 0xff << 24;int red, green, blue;int width = sourceInfo.width;int height = sourceInfo.height;int w, h;for (h = 0; h < height; h++) {for (w = 0; w < width; w++) {color = sourceData[h*width+w];red = (color & 0x00ff0000) >> 16;green = (color & 0x0000ff00) >> 8;blue = color & 0x000000ff;// rgb颜色相同就是黑白图片了 取平均值只是一个方案color = (red + green + blue) / 3;targetData[h*width+w] = alpha | (color << 16) | (color << 8) | color;}}AndroidBitmap_unlockPixels(env, source);AndroidBitmap_unlockPixels(env, target);
}

注意Cmake文件要添加库,否则会报找不到 AndroidBitmap_getInfo 等Bitmap方法:

target_link_libraries( ...jnigraphics)

效果:

以上是我仿 这篇博文 写的,但是我看到这篇博文有一条评论,说是像素点在c上存在大小端的问题,于是乎我改了一点代码:

...
for (h = 0; h < height; h++) {for (w = 0; w < width; w++) {color = sourceData[h*width+w];red = (color & 0x00ff0000) >> 16;green = (color & 0x0000ff00) >> 8;blue = color & 0x000000ff;blue += 60;if (blue > 255) {blue = 255;}color = (red + green + blue) / 3;targetData[h*width+w] = alpha | (red << 16) | (green << 8) | blue;}
}
...

这样改之后,界面应该偏冷色,结果却是:

居然是暖色调了,证明的确存在大小端的问题,所以在C层中,Bitmap像素点的值是BGR,而不是RGB,也就是说,高端到低端:B,G,R!所以代码得改一下:

...
for (h = 0; h < height; h++) {for (w = 0; w < width; w++) {color = sourceData[h*width+w];blue = (color & 0x00ff0000) >> 16;green = (color & 0x0000ff00) >> 8;red = color & 0x000000ff;blue += 80;if (blue > 255) {blue = 255;}color = (red + green + blue) / 3;targetData[h*width+w] = alpha | (blue << 16) | (green << 8) | red;}
}
...

这样改了之后,结果就正常为冷色调了:

至于黑白时没有高低端问题呢,是因为color去的是rgb的平均值,所以不论是r+g+b,还是b+g+r,值都是一样!!

通过这个例子,不仅复习了一下NDK操作,而且还知道了Bitmap像素点存在高低端问题!!值了~

参考资料

JNI下使用AndroidBitmap_lockPixels修改位图为黑白照片

Android JNI操作Bitmap实现黑白图片相关推荐

  1. android jni返回bitmap,JNI 层 Bitmap 转 OpenCV Mat

    JNI 层 Bitmap 转 OpenCV Mat Java 提供的图片类型大多是 Bitmap 类型(ARGB_8888 或 RGB_565) 那么如果需要使用 OpenCV 进行处理,需要对 Bi ...

  2. 【Android 内存优化】Android 工程中使用 libjpeg-turbo 压缩图片 ( JNI 传递 Bitmap | 获取位图信息 | 获取图像数据 | 图像数据过滤 | 释放资源 )

    文章目录 一.Bitmap 图像数据处理 二.Java 层 Bitmap 对象转为 JNI 层 bitmap 对象 三.获取 bitmap 中的图像数据 四.过滤 bitmap 中的图像数据 ( 获取 ...

  3. android 图片过滤,android 图片转为bitmap,黑白镜过滤

    图片转bitmap 1.获取图片资源 Bitmap bitmap= BlackWhite(BitmapFactory.decodeResource(getResources(), R.mipmap.t ...

  4. android bitmap 替换指定颜色,Android 实现把bitmap图片的某一部分的颜色改成其他颜色...

    把bitmap图片的某一部分的颜色改成其他颜色 private Bitmap ChangeBitmap(Bitmap bitmap){ int bitmap_h; int bitmap_w; int ...

  5. android 将图片转换成黑白图片

    先调用android的系统工具,获取图片生成bitmap文件,再使用android中的二值化技术,将图片转化成黑白图片,主界面代码: package com.example.blackwhite;im ...

  6. Android 高效显示Bitmap图片

    Android 高效显示Bitmap图片 本文会介绍一些处理与加载Bitmap对象的常用方法,这些技术能够使得程序的UI不会被阻塞,并且可以避免程序超出内存限制.如果我们不注意这些,Bitmap会迅速 ...

  7. android bitmap 替换指定颜色,Android实现把bitmap图片的某一部分的颜色改成其他颜色的方法...

    Android实现把bitmap图片的某一部分的颜色改成其他颜色的方法 发布时间:2020-07-29 14:11:15 来源:亿速云 阅读:107 作者:小猪 这篇文章主要讲解了Android实现把 ...

  8. Android Bitmap转换WebP图片导致损坏的分析及解决方案

    Android Bitmap转换WebP图片导致损坏的分析及解决方案 参考文章: (1)Android Bitmap转换WebP图片导致损坏的分析及解决方案 (2)https://www.cnblog ...

  9. Android下利用Bitmap切割图片

    在自己自定义的一个组件中由于需要用图片显示数字编号,而当前图片就只有一张,上面有0-9是个数字,于是不得不考虑将其中一个个的数字切割下来,需要显示什么数字,只需要组合一下就好了. 下面是程序的关键代码 ...

最新文章

  1. CNVD初次获取的源代码格式
  2. sublime使用总结
  3. Common BeanUtils组件的使用(源码)
  4. 在ASP.Net Core 中使用枚举类而不是枚举
  5. 怎样对付win7黑屏
  6. 眼下很多创业者之所以会创业失败
  7. Qt与MySQL通信错误及解决方法
  8. Idea编写简单Java网络爬虫程序(maven)
  9. PHP实现倒计时插件代码
  10. flask-uploads
  11. 小明的爷爷108岁了,而我30岁才开始学编程
  12. 【朝花夕拾】Android自定义View篇之(十)移动阈值TouchSlop及滑动追踪VelocityTracker...
  13. AngularJs 生命周期$onChanges钩子函数总结
  14. 软考 计算机 都有什么考试内容,了解软考是什么 软考考试流程都包括哪些
  15. 为什么我们说“买东西”,而不说“买南北”?
  16. 密码算法原理与分析:RSA安全与秘钥基础设施
  17. 完美国际2找回老账号服务器,我告诉大家一个找回账号的办法
  18. 解剖Twitter:Twitter系统架构设计分析-2
  19. 【Adams-Car】专栏目录汇总
  20. 搜狗输入法突然变成繁体怎么解决?

热门文章

  1. 狙击女王的“柳德米拉·米哈伊尔洛夫娜·帕夫利琴科”。
  2. excel中取整和取模函数
  3. vivi tws air pro
  4. 过分!虾皮被曝大范围毁约;深度学习技巧全辑;MongoDB开源替代 4.7K★;剑指Offer解题代码;大数据算法笔记汇总;前沿论文 | ShowMeAI资讯日报
  5. 罗剑锋透视HTTP协议学习笔记---24 | 固若金汤的根本(上):对称加密与非对称加密
  6. JS给input框赋值
  7. jQuery为input赋值(调用函数)
  8. C语言文件操作函数详解
  9. 使用xtrabackup远程备份到及重建数据库
  10. R语言用CPV模型的房地产信贷信用风险的度量和预测