这次使用的场景是QQ好友下线后头像变黑白
使用了NDK中提供的位图解析接口
android\bitmap.h库中的三个接口 并且一共也是三个接口 至少到目前为止是三个
关于这个库的接口 点击查看android-ndk-r9d\android\bitmap.h

好友下线的效果图如下(图片尺寸900*675,位深度24)

android部分代码
public class MainActivity extends Activity {private ImageView ivDisplay = null;private Bitmap bitmapOrig = null;private Bitmap bitmapGray = null;private Bitmap bitmapWip = null;static {System.loadLibrary("bitmapdemo");}public native void convertBmp(Bitmap bitmapIn, Bitmap bitmapOut);Boolean isColor;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ivDisplay = (ImageView) findViewById(R.id.ivDisplay);BitmapFactory.Options options = new BitmapFactory.Options();options.inPreferredConfig = Config.ARGB_8888;bitmapOrig = BitmapFactory.decodeResource(this.getResources(),R.drawable.sampleimage, options);if (bitmapOrig != null)ivDisplay.setImageBitmap(bitmapOrig);isColor = true;bitmapWip = Bitmap.createBitmap(bitmapOrig.getWidth(),bitmapOrig.getHeight(), Config.ARGB_8888); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if(isColor){isColor = false;convertBmp(bitmapOrig, bitmapWip);ivDisplay.setImageBitmap(bitmapWip);}else{isColor = true;ivDisplay.setImageBitmap(bitmapOrig);}}});}
}
jni部分代码
typedef struct
{uint8_t alpha;uint8_t red;uint8_t green;uint8_t blue;
} argb;/*
* convertToGray
* Pixel operation
*/
JNIEXPORT void JNICALL Java_com_example_bitmapdemo_MainActivity_convertBmp(JNIEnv * env, jobject  obj, jobject jsrcBitmap, jobject desBitmap){AndroidBitmapInfo srcInfo, dstInfo;if (ANDROID_BITMAP_RESULT_SUCCESS != AndroidBitmap_getInfo(env, jsrcBitmap, &srcInfo)|| ANDROID_BITMAP_RESULT_SUCCESS != AndroidBitmap_getInfo(env, desBitmap, &dstInfo)) {LOGE("get bitmap info failed");return;}void *srcBuf, *dstBuf;if (ANDROID_BITMAP_RESULT_SUCCESS != AndroidBitmap_lockPixels(env, jsrcBitmap, &srcBuf)) {LOGE("lock src bitmap failed");return;}if (ANDROID_BITMAP_RESULT_SUCCESS != AndroidBitmap_lockPixels(env, desBitmap, &dstBuf)) {LOGE("lock dst bitmap failed");return;}LOGI("width=%d; height=%d; stride=%d; format=%d;flag=%d",srcInfo.width, //  width=2700 (900*3)srcInfo.height, // height=2025 (675*3)srcInfo.stride, // stride=10800 (2700*4)srcInfo.format, // format=1 (ANDROID_BITMAP_FORMAT_RGBA_8888=1)srcInfo.flags); // flags=0 (ANDROID_BITMAP_RESULT_SUCCESS=0)int w = srcInfo.width;int h = srcInfo.height;int32_t *srcPixs = (int32_t *) srcBuf;int32_t *desPixs = (int32_t *) dstBuf;int alpha = 0xFF << 24;int i, j;int color;int red;int green;int blue;for (i = 0; i < h; i++) {for (j = 0; j < w; j++) {// get the color of per pixel color = srcPixs[w * i + j];red = ((color & 0x00FF0000) >> 16);green = ((color & 0x0000FF00) >> 8);blue = color & 0x000000FF;color = (red + green + blue) / 3;color = alpha | (color << 16) | (color << 8) | color;desPixs[w * i + j] = color;}}AndroidBitmap_unlockPixels(env, jsrcBitmap);AndroidBitmap_unlockPixels(env, desBitmap);
}

主要通过AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr)对图片进行解码并获取解码后像素保存在内存中的地址指针addrPtr,通过对addrPtr指向的内存空间进行像素修改,就相当于直接修改了被加载到内存中的位图
调用AndroidBitmap_unlockPixels释放锁定 在内存中被修改的位图数据就可以用于显示到前台

这里的去彩色的计算方法就是把RGB三个颜色值平均即可,即是从白到黑的深浅程度的值
图片的RGB三个通道值如果一样颜色就是灰色的,通道的值越小越黑,越大越白
当RGB都是255就是白色。如果RGB都是0就是黑

这里获取到的跨距srcInfo.stride=10800=900*3*4 这里不对跨距进行展开讨论
可以学习yuv以及stride跨距的相关知识点进行了解

关于图片解码部分可以参考 libpng的png_read_info和png_read_image使用实例分析

点击查看完整例程源代码AndroidBitmapDemo

JNI下使用AndroidBitmap_lockPixels修改位图为黑白照片相关推荐

  1. Android下基于SDL的位图渲染(一)

    环境准备 安装Android开发环境(java.android-sdk.android ndk.gcc). 我使用的ndk版本是r10b/r10d,在win10/ubutu 15.04编译 下载sdl ...

  2. linux下root密码修改方法

    linux下root密码修改方法 以root身份登陆,执行: passwd 用户名   修改密码. useradd 用户名   添加用户. 具体的如下:    #passwd   root    输入 ...

  3. win2008 mysql端口_Win7系统下SqlServer 2008修改IP端口的方法

    当我们在win7系统中使用SqlServer 2008连接数据库的时候,发现需要使用连接数据库ip端口,可是许多win732位系统用户并不知道SqlServer 2008怎么修改IP端口,想必有很多人 ...

  4. linux修改隐藏文件生效,在Linux传统文件系统下隐藏属性的修改-linux修改文件名...

    在Linux传统文件系统下隐藏属性的修改 在Linux系统中,一个文件有若干个属性,如读写执行(r.w.x)等基本权限,以及表达这个文件类型的一些属性,如是否为文件"-"或目录&q ...

  5. Linux下设置和修改IP

    在网上查找了配置linux配置IP的方法,简单的有下面两种: 最常用的给网卡配置ip的命令为 #ifconfig eth0 192.168.0.1 netmask 255.255.255.0 up 说 ...

  6. linux下limits.conf 修改不生效的原因

    简介 ELK环境搭建时,发现需要修改ulimit 设置,否则就会报错. 总结下来发现要使limits.conf生效,需要设置 UsePAM yes UseLogin yes #这个保证其他的用户也能修 ...

  7. layui select(下拉框)修改事件监听

    layui select(下拉框)修改事件监听示例(节选): 当下拉框选项修改后,自动执行my_function函数. HTML部分: <select id="camera_strea ...

  8. 【Element ui 的NavMenu二级菜单下拉icon修改】

    Element ui 的NavMenu二级菜单下拉icon修改 原来是这样的,下拉icon在右边 修改成icon在左边,并更改icon的形状 修改icon的css属性,覆盖原来的.需要注意的是取消打开 ...

  9. Windows 修改键盘映射(附带Linux下Ubuntu的修改方法)

    Windows 修改键盘映射(附带Linux下Ubuntu的修改方法) 一.简述        通过修改键盘映射关系可以改变按键的功能.如:       1) A键损坏,使用B键代替.       2 ...

最新文章

  1. pku1182(食物链) hdu3047 Zjnu Stadium
  2. csu 1554: SG Value 思维题
  3. 彩虹背光:芝奇推出KM570 RGB机械游戏键盘
  4. c语言指针的自我评价,个人自我评价
  5. springmvc @PathVariable注解进行传参操作
  6. java显示星期几_Java 使用日历显示星期几
  7. oracle 重复的记录数,如何确定Oracle数据库表中重复的记录
  8. es6删除数组某项_es6删除数组元素或者对象元素的方法介绍(代码)
  9. 组网胖模式_胖AP和瘦AP的区别,组网优缺点分析
  10. Django学习-19-缓存
  11. java多线程基础(synchronize关键字)
  12. DesignSurface简介
  13. day3-python的基础类源码解析——collection类
  14. 计算机通过注册表修改摄像机设备的名称
  15. 简单数独的DFS求解
  16. python背景怎么自定义铃声_【Python成长之路】如何用2行代码将抖音视频设置成我的手机铃声...
  17. 免越狱版 iOS 抢红包插件
  18. 计算机二级vb考试题库app,全国计算机二级vb考试题库
  19. 工程项目管理系统java程序,基于jsp的工程项目管理系统-JavaEE实现工程项目管理系统 - java项目源码...
  20. 在虚拟机中安装Neokylin操作系统

热门文章

  1. sis防屏蔽程序是什么意思_如何搭建小程序商城,流量私域化是什么意思?-社交电商资讯_社区团购系统,社区团购小程序,社群团购系统,社交电商系统,专注社区团购系统研发...
  2. JAVA(景区门票类)
  3. jQuery学习笔记之unbind()
  4. Xcode如何通过Coding.net托管代码
  5. 嵌入式应该如何学习,高手建议如何学习嵌入式系统
  6. 云计算机教室怎样使用,学校使用云教室是一种怎样的体验
  7. #HPDC 华为伙伴暨开发者大会2022随笔
  8. CocoaPods 重装
  9. cocoapods插件安装目录
  10. 系统bug是什么意思