jni与bitmap
来源:互联网 发布:佳明官网下载软件 编辑:程序博客网 时间:2024/06/05 19:01
说明
本文c代码来自于ndk demo。主要演示在ndk中如何操作bitmap对象,改变bitmap中的某些像素值。利用该功能再结合相应的算法,可实现将图片置灰等功能。
颜色
除了常用的rgb8888外,还有rgb565模式。
rgb565:用16位表示一个颜色,从高位到低位如下:R R R R R G G G G G G B B B B B。因此在该种模式下红色为0xf800,绿色为0x7e0,蓝色为0x1f。
基础
第一步:要导入#include <android/bitmap.h>头文件。
第二步:在ldLibs的值中加入"jnigraphics"。如下:
ndk { moduleName "ImageJniUtils" //生成的so名字 ldLibs "log","jnigraphics" //可以使用log与graphics abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库,目前可有可无 }
方法
AndroidBitmap_getInfo:获取一个AndroidBitmapInfo的结构体对象。利用该对象可以获取bitmap的format,height,width等信息。只有在该方法返回值>0的时才代表该方法执行成功。
AndroidBitmap_lockPixels:用于获取bitmap像素数组的地址。bitmap的每一个像素值都是一个int数值,它们存储在一个数组中(Bitmap#getPixels()会将这些数值存储到指定的数组中)。获取地址后就可以对每一个像素进行操作了。
AndroidBitmap_unlockPixels:与上面一个方法相反,它是释放地址。
示例
示例一:基本使用
void* pixels; if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) { LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); return; } if (info.format != ANDROID_BITMAP_FORMAT_RGB_565) { LOGE("Bitmap format is not RGB_565 !"); return; } if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {//此时pixels便指向了像素数组的首地址 LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); } /* Now fill the values with a nice little plasma */ fill_plasma(&info, pixels, time_ms ); AndroidBitmap_unlockPixels(env, bitmap);对于pixels的使用如下(来自于置灰demo):
void *pixel = ((uint16_t *)pixels) + y * info.width + x; uint16_t v = *(uint16_t *)pixel; //ARGB_565共16位,所以使用unit16_t r = RGB565_R(v); //获取对应的r通道值 g = RGB565_G(v); //获取对应的g通道值 b = RGB565_B(v); //获取对应的b通道值int gray = (r * 38 + g * 75 + b * 15) >> 7; //将获取到的三通道值改变 *((uint16_t *)pixel) = MAKE_RGB565(gray, gray, gray); //将改变后的值存储到原来的位置,这样就改变了这个位置上的像素值
示例二,微信红包图片
先将要保留的范围内的像素值单独存储,等图片模糊后再将范围内的像素值恢复。模糊代码的来源。如下:int Edge(int x, int y, int radius, int centerX, int centerY) { return sqrt((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY)) < radius && abs(y - centerY) <= radius && abs(x - centerX) <= radius;}JNIEXPORT void JNICALL Java_com_baigle_image_ImageUtils_blur(JNIEnv *env, jobject obj, jobject bitmap, jint width, jint height) { AndroidBitmapInfo info; void *pixels; int ret; if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) { LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); return; } if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); return; } int centerX = info.width / 2; int centerY = info.height / 3; int shortP = info.width > info.height ? info.height : info.width; int radius = shortP / 8;//确定保留半径 int x, y = centerY - radius; void *dst = malloc((2 * radius + 1) * (2 * radius + 1) * sizeof(int)); for (; y <= centerY + radius; y++) {//保留像素值 for (x = centerX - radius; x <= centerX + radius; x++) { if (Edge(x, y, radius, centerX, centerY)){ *((int *) dst + (y - centerY + radius) * (2 * radius + 1) + x - centerX + radius) = *((int *) pixels + y * info.width + x); } } } blur((int *) pixels, info.width, info.height, 100);//调用模糊方法进行模糊 for (y = centerY - radius; y <= centerY + radius; y++) {//还原保留区域内的像素值 for (x = centerX - radius; x <= centerX + radius; x++) { if (Edge(x, y, radius, centerX, centerY)) *((int *) pixels + y * info.width + x) = *((int *) dst + (y - centerY + radius) * (2 * radius + 1) + x - centerX + radius); } } free(dst); AndroidBitmap_unlockPixels(env, bitmap);}在使用图片时,将图片转换成ARGB_8888。如下:
mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.xxxxxxx); mBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888,false);
0 0
- jni与bitmap
- JNI获取Bitmap轮廓
- JNI---ILandroid/graphics/Bitmap;
- jni操作bitmap
- bitmap与2bitmap实现
- bitmap与2bitmap实现
- bitmap与2bitmap实现
- JNI 无法确定Bitmap的签名
- Android jni开发中使用bitmap
- Bitmap与BitmapData
- Android Bitmap与Canvas
- Bitmap与BitmapData整理
- CBITMAP与BITMAP
- Bitmap与Canvas
- drawable与bitmap
- drawable与bitmap转换
- Bitmap与Drawable互转
- Bitmap与Shader
- Maven搭建SpringMVC+Mybatis项目详解
- 算法导论第三版习题6.2
- ngx_lua_waf利用HPP完全绕过防御机制
- iOS 设计模式 - 桥接模式
- GCD 和延时调用
- jni与bitmap
- [c++新手学习]windows下如何使用c++播放mp3
- Android Screen Monitor同步手机屏幕到PC
- ytu 1072 链表合并
- Web Service和WCF的到底有什么区别
- linux学习--字符设备驱动
- utilities(C++)——错误提示
- 【MFC-11】VS2010/MFC基于对话框程序之修改Enter/ESC按键默认响应
- 51单片机中断学习