在Android的开发中,我们有时会对性能要求比较高。Android通过NDK为我们提供了c++开发的方式。我们可以通过c++完成核心的耗时的计算然后通过JNI的方式将处理完成的数据传给Java层。
今天,我们就用jni的方式对Bitmap进行处理,来实践NDK开发的方式。开发一个图片滤镜。
效果图:

1.CMakeLists.txt 配置

target_link_libraries( # Specifies the target library.                       native-lib                        jnigraphics//android提供的图像处理库                       # Links the target library to the log library                       # included in the NDK.                       ${log-lib} )

2.代码部分

Activity 部分:

 private void initview(){        source_img = (ImageView)findViewById(R.id.source_img);        operation_img = (ImageView)findViewById(R.id.operation_img);        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.newpic);//        operation_img.setImageBitmap(rotateBitmap(bitmap));        operation_img.setImageBitmap(handleBitmap(bitmap));    }    /**     * 处理图片,此方法中会调用nativeProcessBitmap     * @param bitmap     * @return     */    private Bitmap handleBitmap(Bitmap bitmap) {        Bitmap bmp = bitmap.copy(Bitmap.Config.ARGB_8888, true);        nativeProcessBitmap(bmp);        return bmp;    }        /**     * 黑白特效     */    public native void nativeProcessBitmap(Bitmap bitmap);

2.jni 部分:

#include #include #include #include #include #include "AndroidLog.h"#include #define MAKE_RGB565(r,g,b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))#define MAKE_ARGB(a,r,g,b) ((a&0xff)<<24) | ((r&0xff)<<16) | ((g&0xff)<<8) | (b&0xff)#define RGB565_R(p) ((((p) & 0xF800) >> 11) << 3)#define RGB565_G(p) ((((p) & 0x7E0 ) >> 5)  << 2)#define RGB565_B(p) ( ((p) & 0x1F  )        << 3)#define RGB8888_A(p) (p & (0xff<<24) >> 24 )#define RGB8888_R(p) (p & (0xff<<16) >> 16 )#define RGB8888_G(p) (p & (0xff<<8)  >> 8 )#define RGB8888_B(p) (p & (0xff) )#define RGBA_A(p) (((p) & 0xFF000000) >> 24)#define RGBA_R(p) (((p) & 0x00FF0000) >> 16)#define RGBA_G(p) (((p) & 0x0000FF00) >>  8)#define RGBA_B(p)  ((p) & 0x000000FF)#define MAKE_RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))extern "C" JNIEXPORT void JNICALLJava_com_xinrui_ndkapp_MainActivity_nativeProcessBitmap(JNIEnv *env,                                                                        jobject instance,                                                                        jobject bitmap) {    if (bitmap == NULL) {        LOGE("bitmap is null\n");        return;    }    AndroidBitmapInfo bitmapInfo;    memset(&bitmapInfo , 0 , sizeof(bitmapInfo));    // Need add "jnigraphics" into target_link_libraries in CMakeLists.txt    AndroidBitmap_getInfo(env , bitmap , &bitmapInfo);    // Lock the bitmap to get the buffer    void * pixels = NULL;    int res = AndroidBitmap_lockPixels(env, bitmap, &pixels);    // From top to bottom    int x = 0, y = 0;    for (y = 0; y < bitmapInfo.height; ++y) {        // From left to right        for (x = 0; x < bitmapInfo.width; ++x) {            int a = 0, r = 0, g = 0, b = 0;            void *pixel = NULL;            // Get each pixel by format            if(bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888)            {                pixel = ((uint32_t *)pixels) + y * bitmapInfo.width + x;                int r,g,b;                uint32_t v = *((uint32_t *)pixel);                r = RGB8888_R(v);                g = RGB8888_G(v);                b = RGB8888_B(v);                int sum = r+g+b;                *((uint32_t *)pixel) = MAKE_ARGB(0xff , sum/3, sum/3, sum/3);            }            else if (bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGB_565) {                pixel = ((uint16_t *)pixels) + y * bitmapInfo.width + x;                int r,g,b;                uint16_t v = *((uint16_t *)pixel);                r = RGB565_R(v);                g = RGB565_G(v);                b = RGB565_B(v);                int sum = r+g+b;                *((uint16_t *)pixel) = MAKE_RGB565(sum/3, sum/3, sum/3);  }        }    }    AndroidBitmap_unlockPixels(env, bitmap);}

更多相关文章

  1. GitHub 标星 2.5K+!教你通过玩游戏的方式学习 VIM!
  2. Android(安卓)实现锁屏的较完美方案
  3. Android(安卓)App发布流程----签名
  4. Android(安卓)RecyclerView利用Glide加载大量图片into(Target)导
  5. jadx:好用的反编译工具
  6. android 四大组件之Service两种调用方式使用详解
  7. Android创建桌面快捷方式两种方法
  8. ReactNative中把js编译成bundle后,js引用的图片的去向
  9. Android(安卓)远程图片获取和本地缓存策略

随机推荐

  1. Android(安卓)中Ninja 简介
  2. android中SharedPreferences用法详解
  3. android中scaleType详解
  4. Android深入浅出之Zygote
  5. Android(安卓)的 Activity 组件详解
  6. Android(安卓)中 Service 学习,总结
  7. Android(安卓)onDraw
  8. 写在20110626:NDK、JNI
  9. Android(安卓)Toast 长期显示解决方案
  10. Android(安卓)怎么样使用shape