Android JNI 开发 Demo by NDK (native develop kit)
来源:互联网 发布:济南整站优化方案 编辑:程序博客网 时间:2024/05/22 13:44
最近终于有了一些空闲时间,所以想着把之前的Android相关的项目整理一下,前几天整理了Android OCR 的项目, 今天就干脆再整理一下 NDK JNI调用。
关于Android 中通过JNI进行本地调用的配置与开发,已经在链接 http://blog.csdn.net/watkinsong/article/details/9849973 中给出了非常详细的说明。 请仔细阅读。
同时,关于Android 作OCR的说明,也已经 在 http://blog.csdn.net/watkinsong/article/details/45541215 给出了详细的解释。 所以,本文章不再赘述如何配置开发环境,如何创建项目等,而是直接给出一个项目,列出需要注意的几点要点。
1. 首先,通过https://github.com/weixsong/libra 链接下载该项目,找到NDKDemo项目。
2. 通过Eclipse导入项目。
3. 在调用JNI之前,我们需要定义一个接口,实现和JNI通讯,本例的接口定义:
package com.example.ndk;public class CannyDetect {static {System.loadLibrary("native");}/** * @param width * the current view width * @param height * the current view height */public static native int[] cannyDetect(int[] buf, int w, int h);}
接口中,要通过静态初始化代码块加载.so文件,不需要添加后缀名。 然后定义static native 的接口,这个接口需要符合JNI的规范。
4. 既然有了JNI调用接口,就要看看如何编写JNI程序:
在native.cpp 中:
#include <jni.h>#include <stdio.h>#include <stdlib.h>#include <opencv2/opencv.hpp>using namespace cv;IplImage * change4channelTo3InIplImage(IplImage * src);extern "C" {JNIEXPORT jintArray JNICALL Java_com_example_ndk_CannyDetect_cannyDetect(JNIEnv* env, jobject obj, jintArray buf, int w, int h);JNIEXPORT jintArray JNICALL Java_com_example_ndk_CannyDetect_cannyDetect(JNIEnv* env, jobject obj, jintArray buf, int w, int h) {jint *cbuf;cbuf = env->GetIntArrayElements(buf, 0);if (cbuf == NULL) {return 0;}Mat myimg(h, w, CV_8UC4, (unsigned char*) cbuf);IplImage image = IplImage(myimg);IplImage* image3channel = change4channelTo3InIplImage(&image);IplImage* pCannyImage = cvCreateImage(cvGetSize(image3channel),IPL_DEPTH_8U, 1);cvCanny(image3channel, pCannyImage, 50, 150, 3);int* outImage = new int[w * h];for (int i = 0; i < w * h; i++) {outImage[i] = (int) pCannyImage->imageData[i];}int size = w * h;jintArray result = env->NewIntArray(size);env->SetIntArrayRegion(result, 0, size, outImage);env->ReleaseIntArrayElements(buf, cbuf, 0);return result;}}IplImage * change4channelTo3InIplImage(IplImage * src) {if (src->nChannels != 4) {return NULL;}IplImage * destImg = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);for (int row = 0; row < src->height; row++) {for (int col = 0; col < src->width; col++) {CvScalar s = cvGet2D(src, row, col);cvSet2D(destImg, row, col, s);}}return destImg;}
之前的博客评论中,总是有些小伙伴说哎呀,JNI找不到函数阿神码神码的,麻烦您先彻底看清楚博客怎么写的。。。
这里再强调一下:
JNIEXPORT jintArray JNICALL Java_com_example_ndk_CannyDetect_cannyDetect (***)
这个函数的声明,一定要遵循JNI的标准规范,首先是
JNIEXPORT jintArray JNICALL
然后, Java_ + 包名称,其中,包中的点用_代替,然后,步骤3中定义的接口的类名,然后是方法名。
5. 注意一下Android.mk文件:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)OPENCV_LIB_TYPE:=STATICOPENCV_INSTALL_MODULES:=onOPENCV_CAMERA_MODULES:=offifeq ("$(wildcard $(OPENCV_MK_PATH))","")#try to load OpenCV.mk from default install locationinclude /home/wesong/software/OpenCV-2.4.10-android-sdk/sdk/native/jni/OpenCV.mkelseinclude $(OPENCV_MK_PATH)endifLOCAL_MODULE := nativeLOCAL_SRC_FILES := native.cppLOCAL_LDLIBS += -llog -ldlinclude $(BUILD_SHARED_LIBRARY)
修改里面的OpenCV.mk的路径。
6. 看一眼 Application.mk
APP_STL:=gnustl_static APP_CPPFLAGS:=-frtti -fexceptions APP_ABI:=armeabi armeabi-v7aAPP_PLATFORM := android-19
7. 主程序:
package com.example.ndk;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.drawable.BitmapDrawable;import android.os.Bundle;import android.widget.Button;import android.view.View;import android.widget.ImageView;public class MainActivity extends Activity {ImageView imgView;Button btnNDK, btnRestore;private String title = "Canny detect by NDK";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.setTitle(title);btnRestore = (Button) this.findViewById(R.id.btnRestore);btnRestore.setOnClickListener(new ClickEvent());btnNDK = (Button) this.findViewById(R.id.btnNDK);btnNDK.setOnClickListener(new ClickEvent());imgView = (ImageView) this.findViewById(R.id.ImageView01);Bitmap img = ((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();imgView.setImageBitmap(img);}class ClickEvent implements View.OnClickListener {public void onClick(View v) {if (v == btnNDK) {long current = System.currentTimeMillis();Bitmap img1 = ((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();int w = img1.getWidth(), h = img1.getHeight();int[] pix = new int[w * h];img1.getPixels(pix, 0, w, 0, 0, w, h);int[] resultInt = CannyDetect.cannyDetect(pix, w, h);Bitmap resultImg = Bitmap.createBitmap(w, h, Config.RGB_565);resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);long performance = System.currentTimeMillis() - current;imgView.setImageBitmap(resultImg);MainActivity.this.setTitle("NDK consumed: "+ String.valueOf(performance) + " ms");} else if (v == btnRestore) {Bitmap img2 = ((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();imgView.setImageBitmap(img2);MainActivity.this.setTitle("使用OpenCV进行图像处理");}}}}
截图:
1 0
- Android JNI 开发 Demo by NDK (native develop kit)
- Android Native Development Kit (NDK)
- Android Studio NDK-Jni开发小Demo
- android NDK/JNI demo
- JNI/NDK develop guide(2) How JVM find native method
- 初识 Android Native Development Kit (NDK)
- Android NDK 环境搭建(Native Development Kit )
- Android NDK: Native Development Kit 入坑篇
- Android Studio ndk-Jni开发详细入门,Aes加密demo
- Android Studio ndk-Jni开发详细入门,Aes加密demo
- Android JNI/NDK 开发
- Android ndk 开发demo
- NDK全称 Native Development Kit
- NDK全称 Native Development Kit
- NDK JNI开发配置以及Demo
- Android NDK JNI 简单调试 demo
- Android NDK开发----- JNI多线程
- Android JNI(NDK)开发总结
- 【leetcode with java】8 String to Integer (atoi)
- 图像搜索算法
- Leetcode 75Sort Colors
- ARM Linux 设置时间
- PDF转Word神器—ABBYY FineReader,这个必须有!(图文)
- Android JNI 开发 Demo by NDK (native develop kit)
- 谷歌火狐浏览器用append()方法,不能实现ajax刷新问题
- 5+ App开发入门指南
- 奇葩的生命周期
- 快速安装nagios(官网译文)+客户端+自定义监控
- Debug on real Apple Watch: Application Verification Failed
- 通过代码自定义cell,cell的高度不一致
- String、StringBuffer、StringBuilder的区别和使用
- Java课程教学方法探讨——作为入门教学语言的争议及其分析