zoukankan      html  css  js  c++  java
  • 深入了解android平台的jni---图像灰度化处理

    一、涉及到的jni编程知识
    Java基本类型的数组,在JNI中都是jArray的类型格式。具体类型如下:
    typedef jarray jbooleanArray;
    typedef jarray jbyteArray;
    typedef jarray jcharArray;
    typedef jarray jshortArray;
    typedef jarray jintArray;
    typedef jarray jlongArray;
    typedef jarray jfloatArray;
    typedef jarray jdoubleArray;
    typedef jarray jobjectArray;
    jArray类型JNI定义的类型,通过它JNIEnv可以操作Java数组,但它并不是C/C++的数组,所以我们要把jArray类型转换为C/C++中的数组。
    JNIEnv定义了一系列的方法来把一个jArray类型转换为C/C++数组,和把C/C++数组转换为jArray
    1、Java基本类型的数组转换成相应的C数组类型 
        jboolean*   (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
        jbyte*      (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
        jchar*      (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
        jshort*     (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
        jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
        jlong*      (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
        jfloat*     (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
        jdouble*    (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);
    参数:
    env:JNI 接口指针。        
    array:Java 字符串对象。        
    isCopy:指向布尔值的指针。        
    返回值:        
    返回指向数组元素的指针,如果操作失败,则为 NULL。
    2、获取数组的长度:
         jsize       (*GetArrayLength)(JNIEnv*, jarray);
    3、释放C/C++的数组内存
         void        (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,jboolean*, jint); 
         void        (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,jbyte*, jint);
         void        (*ReleaseCharArrayElements)(JNIEnv*, jcharArray,jchar*, jint);
         void        (*ReleaseShortArrayElements)(JNIEnv*, jshortArray,jshort*, jint);
         void        (*ReleaseIntArrayElements)(JNIEnv*, jintArray,jint*, jint);
         void        (*ReleaseLongArrayElements)(JNIEnv*, jlongArray,jlong*, jint);
         void        (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,jfloat*, jint);
         void        (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,jdouble*, jint);
    参数:        
    env:JNI 接口指针。        
    array:Java 数组对象。        
    elems:指向数组元素的指针。        
    mode:释放模式。
    4、构造一个指定长度的Java基本类型的数组
         jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
         jbyteArray    (*NewByteArray)(JNIEnv*, jsize);
         jcharArray    (*NewCharArray)(JNIEnv*, jsize);
         jshortArray   (*NewShortArray)(JNIEnv*, jsize);
         jintArray     (*NewIntArray)(JNIEnv*, jsize);
         jlongArray    (*NewLongArray)(JNIEnv*, jsize);
         jfloatArray   (*NewFloatArray)(JNIEnv*, jsize);
         jdoubleArray  (*NewDoubleArray)(JNIEnv*, jsize); 
    5、给java基本类型的数组赋值
         void  (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,jsize, jsize, const jboolean*);
         void  (*SetByteArrayRegion)(JNIEnv*, jbyteArray,jsize, jsize, const jbyte*);
         void  (*SetCharArrayRegion)(JNIEnv*, jcharArray,jsize, jsize, const jchar*);
         void  (*SetShortArrayRegion)(JNIEnv*, jshortArray,jsize, jsize, const jshort*);
         void  (*SetIntArrayRegion)(JNIEnv*, jintArray,jsize, jsize, const jint*);
         void  (*SetLongArrayRegion)(JNIEnv*, jlongArray,jsize, jsize, const jlong*);
         void  (*SetFloatArrayRegion)(JNIEnv*, jfloatArray,jsize, jsize, const jfloat*);
         void  (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray, jsize, jsize, const jdouble*); 
    把java基本类型的数组中的指定范围的元素用C/C++的数组中的元素来赋值
    参数:        
    env:JNI 接口指针。        
    array:  Java 数组。        
    start:起始下标。        
    len:要复制的元素数。        
    buf:源缓冲区。        
    抛出:        
    ArrayIndexOutOfBoundsException:如果区域中的某个下标无效。
    注意:
    如果是c程序,要用 (*env)-> 
    如果是C++要用 env->
    在linux下如果.c文件中用 “env->” 编译会找不到此结构,必须用“(*env)->”,或者改成.cpp文件,以 c++的方式来编译。
    具体请看一下jni.h的代码。另外还有些省略的内容,可以参考JNI的文档:Java Native Interface 6.0 Specification,在JDK的文档里就可以找到。如果要进行更深入的JNI编程,需要仔细阅读这个文档
     
    二、图像灰度化
    彩色转灰度的著名心理学公式:Gray = R*0.299 + G*0.587 + B*0.114
    实际应用中为了避免浮点运算,然后就有了移位运算代替了。
    2至20位精度的系数:
    Gray = (R*1 + G*2 + B*1) >> 2 
    Gray = (R*2 + G*5 + B*1) >> 3 
    Gray = (R*4 + G*10 + B*2) >> 4 
    Gray = (R*9 + G*19 + B*4) >> 5 
    Gray = (R*19 + G*37 + B*8) >> 6 
    Gray = (R*38 + G*75 + B*15) >> 7 
    Gray = (R*76 + G*150 + B*30) >> 8 
    Gray = (R*153 + G*300 + B*59) >> 9 
    Gray = (R*306 + G*601 + B*117) >> 10 
    Gray = (R*612 + G*1202 + B*234) >> 11 
    Gray = (R*1224 + G*2405 + B*467) >> 12 
    Gray = (R*2449 + G*4809 + B*934) >> 13 
    Gray = (R*4898 + G*9618 + B*1868) >> 14 
    Gray = (R*9797 + G*19235 + B*3736) >> 15 
    Gray = (R*19595 + G*38469 + B*7472) >> 16 
    Gray = (R*39190 + G*76939 + B*14943) >> 17 
    Gray = (R*78381 + G*153878 + B*29885) >> 18 
    Gray = (R*156762 + G*307757 + B*59769) >> 19 
    Gray = (R*313524 + G*615514 + B*119538) >> 20
     
    三、灰度化代码实现
    JNIEXPORT jintArray JNICALL Java_org_join_image_util_JoinImage_imgToGray( 
            JNIEnv* env, jobject obj, jintArray buf, int w, int h) { 
        LOGE("==imgToGray=="); 
     
        jint * cbuf; 
        cbuf = (*env)->GetIntArrayElements(env, buf, 0); // 获取int数组元素 
       
        int alpha = 0xFF; // 不透明值 
        int i, j, color, red, green, blue; 
        for (i = 0; i < h; i++) { 
            for (j = 0; j < w; j++) { 
                color = cbuf[w * i + j]; // 获得color值 
                red = (color >> 16) & 0xFF; // 获得red值 
                green = (color >> 8) & 0xFF; // 获得green值 
                blue = color & 0xFF; // 获得blue值 
                color = (red * 38 + green * 75 + blue * 15) >> 7; // 灰度算法(16位运算下7位精度) 
                color = (alpha << 24) | (color << 16) | (color << 8) | color; // 由ARGB组成新的color值 
                cbuf[w * i + j] = color; // 设置新color值 
            } 
        } 
     
        int size = w * h; 
        jintArray result = (*env)->NewIntArray(env, size); // 新建一个jintArray 
        (*env)->SetIntArrayRegion(env, result, 0, size, cbuf); // 将cbuf转存入result 
        (*env)->ReleaseIntArrayElements(env, buf, cbuf, 0); // 释放int数组元素 
        return result; 
     
     
    本文欢迎转载,但请注明出处与作者
    出处:http://blog.sina.com.cn/staratsky
    作者:流星
  • 相关阅读:
    Atitti 图像处理 图像混合 图像叠加 blend 原理与实现
    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
    Atitit 图像处理 灰度图片 灰度化的原理与实现
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    Atitit 实现java的linq 以及与stream api的比较
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像处理 常用8大滤镜效果 Jhlabs 图像处理类库 java常用图像处理类库
    Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结
    Atitit apache 和guava的反射工具
    atitit。企业的价值观 员工第一 vs 客户第一.docx
  • 原文地址:https://www.cnblogs.com/aiguozhe/p/5355221.html
Copyright © 2011-2022 走看看