Jni 常用工具函数

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
//打开路径文件,并抬FileDescriptor
jobject  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 string
jstring 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

void
Java_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提取buf
if ((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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值