Android------JNI的调用方法
1,调用的地方java类
如下:
package com.ming.camera;
//import android.content.Context;
//如果引用了这些外部包,javac时,必须使用/home/ming/Android/Sdk/platforms/android-23/android.jar参数,具体参考2步骤.
//import android.graphics.Bitmap;
public class LibVGestureDetect {
static
{
System.loadLibrary("BlurModoule");
}
public static native void YUVtoRBGA(byte[] yuv420sp, int width, int height, int[] rgbOut);
}
2,使用javac -classpath /home/ming/Android/Sdk/platforms/android-23/android.jar com/ming/camera/LibVGestureDetect.java 生成LibVGestureDetect.class文件
3,在src目录使用javah -classpath . -jni com.ming.camera.LibVGestureDetect 生成.h文件
(在jni开发中,有时候需要传入一个Context类型参数到C层,在使用javah生成头文件的时候,会报 javah Class android.content.Context could not be found.这个错误,原因是找不到android.content.Context该类,解决方法是,把Context类型改为Object类型即可。)
4,如果出现".class: major version 52 is newer than 51, the highest major version supported by this compiler"错误,说明javac 和javah版本不一致.可以使用"update-alternatives --config javac"切换javac版本重新来过
5,添加BlurModoule.so模块,根据.h文件建立BlurModoule.so模块
6,其中.so模块中,NV21toRGBA函数实现如下:
/*
* Class: com_gangyun_camera_LibBlurModule
* Method: NV21toRBGA
* Signature: ([BII[I)V
*/
void JNICALL Java_com_ming_camera_LibBlurModule_NV21toRBGA
(JNIEnv * env, jclass obj, jbyteArray yuv420sp, jint width, jint height, jintArray rgbOut)
{
int sz;
int i;
int j;
int Y;
int Cr = 0;
int Cb = 0;
int pixPtr = 0;
int jDiv2 = 0;
int R = 0;
int G = 0;
int B = 0;
int cOff;
int w = width;int h = height;
sz = w * h;
jint *rgbData = (jint*) ((*env)->GetPrimitiveArrayCritical(env, rgbOut, 0));
jbyte* yuv = (jbyte*) (*env)->GetPrimitiveArrayCritical(env, yuv420sp, 0);
for(j = 0; j < h; j++) {
pixPtr = j * w;
jDiv2 = j >> 1;
for(i = 0; i < w; i++) {
Y = yuv[pixPtr];
if(Y < 0) {
Y += 255;
}
if((i & 0x1) != 1) {
cOff = sz + jDiv2 * w + (i >> 1) * 2;
Cb = yuv[cOff];
if(Cb < 0)
{
Cb += 127;
}
else{
Cb -= 128;
}
Cr = yuv[cOff + 1];
if(Cr < 0)
{
Cr += 127;
}
else{
Cr -= 128;
}
}
R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
if(R < 0) {
R = 0;
}
else if(R > 255) {
R = 255;
}
G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
if(G < 0) {
G = 0;
}
else if(G > 255) {
G = 255;
}
B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
if(B < 0) {
B = 0;
}
else if(B > 255) {
B = 255;
}
//rgbData[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R;
rgbData[pixPtr++] = 0xff000000 + (R << 16) + (G << 8) + B;
}
}
//gaussBlur(rgbData,width,height,5);
(*env)->ReleasePrimitiveArrayCritical(env, rgbOut, rgbData, 0);
(*env)->ReleasePrimitiveArrayCritical(env, yuv420sp, yuv, 0);
}
7,调试对camera数据格式有疑问,调试; 可以用:
public static void writeBytesToFile2(ByteBuffer bss,String filename) throws IOException{
//ByteBuffer bb = ByteBuffer.wrap(bss);
FileChannel fc = new FileOutputStream(filename).getChannel();
fc.write(bss);
fc.close();
}
把camera数据留写成文件, 然后用pYUV工具打开保存的数据流文件;yuv工具下载地址:https://pan.baidu.com/s/1zWulZ9NV2qfuB8FH0jiMJA