一、涉及到的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 = R0.299 + G0.587 + B*0.114 实际应用中为了避免浮点运算,然后就有了移位运算代替了。 2至20位精度的系数:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |  | 
三、灰度化代码实现
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |  |