Jni编程会用到的工具函数,做积累
1. 打开文件路径,返回文件描述符给Java
|
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
28
29
30
|
//打开路径文件,并抬FileDescriptorjobject
openFile(JNIEnv *env, jstring path, jint flags){ int fd; jobject
mFileDescriptor; /*
Opening device */ { jboolean
iscopy; const char *path_utf
= env->GetStringUTFChars(path, &iscopy); fd
= open(path_utf, O_RDWR | flags); env->ReleaseStringUTFChars(path,
path_utf); if (fd
== -1) { /*
Throw an exception */ LOGE("Cannot
open port"); return NULL; } } /*
Create a corresponding file descriptor */ { jclass
cFileDescriptor = env->FindClass("java/io/FileDescriptor"); jmethodID
iFileDescriptor = env->GetMethodID(cFileDescriptor, "<init>", "()V"); jfieldID
descriptorID = env->GetFieldID(cFileDescriptor, "descriptor", "I"); mFileDescriptor
= env->NewObject(cFileDescriptor, iFileDescriptor); env->SetIntField(mFileDescriptor,
descriptorID, (jint)fd); } return mFileDescriptor;} |
2. Char转换成String
|
1
2
3
4
5
6
7
8
9
10
11
|
//char
* to stringjstring
charToString(JNIEnv *env, const char *chr){ LOGI("charToString:
%s\n",
chr); jclass
strClass = env->FindClass("java/lang/String"); jmethodID
strConstruct = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); jbyteArray
bytes = env->NewByteArray(strlen(chr)); env->SetByteArrayRegion(bytes,
0, strlen(chr),
(jbyte*)chr); jstring
encoding = env->NewStringUTF("utf-8"); return (jstring)env->NewObject(strClass,
strConstruct, bytes, encoding);} |
3. String转换为Char
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
//jstring
to char*char*
jstringToChar(JNIEnv* env, jstring jstr){ char*
rtn = NULL; jclass
clsstring = env->FindClass("java/lang/String"); jstring
strencode = env->NewStringUTF("utf-8"); jmethodID
mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray
barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize
alen = env->GetArrayLength(barr); jbyte*
ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen
> 0) { rtn
= (char*)malloc(alen
+ 1); memcpy(rtn,
ba, alen); rtn[alen]
= 0; } env->ReleaseByteArrayElements(barr,
ba, 0); return rtn;} |
4. 上层传一个ByteBuffer给Jni用
Java:
private ByteBuffer mImageBuffer;mImageBuffer = ByteBuffer.allocateDirect(mImageBufferSize);ret = setDirectBuffer(mImageBuffer, mImageBufferSize);
Jni:
jint Java_com_camera_simplewebcam_CameraPreview_setDirectBuffer(JNIEnv *env, jobject thiz,jobject jbuf, jint jlen) {char *pImageBuf = NULL;//获取Buffer首地址pImageBuf = (char *)(*env)->GetDirectBufferAddress(env, jbuf);if (NULL == pImageBuf) {LOGE("Failed to get direct buffer");return -1;}return 0;}
5. 色彩Buffer转换成Bitmap类。
在UVC中把一帧的buffer转换成上层需要显示的Bitmap。Android.mk里要加入库LOCAL_LDLIBS := -ljnigraphics
voidJava_com_camera_simplewebcam_CameraPreview_pixeltobmp( JNIEnv* env,jobject thiz,jobject bitmap){jboolean bo;AndroidBitmapInfo info;void* pixels;int ret;int i;int *colors;int width=0;int height=0;//提取bmp信息if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);return;}width = info.width;height = info.height;if(!rgb || !ybuf) return;if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {LOGE("Bitmap format is not RGBA_8888 !");return;}//bitmap提取bufif ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);}colors = (int*)pixels;int *lrgb =NULL;lrgb = &rgb[0];//把目录buf拷贝到bitmap的buffer里for(i=0 ; i<width*height ; i++){*colors++ = *lrgb++;}AndroidBitmap_unlockPixels(env, bitmap);}
774

被折叠的 条评论
为什么被折叠?



