第一次玩 Android NDK+openCV 就上手

因為最近工作在移植前人寫的code,將C++程式碼重寫成Java程式碼似乎有點不實際

而且我又不太想認真看懂所有程式(眼神死)XD

所以就想試試看很潮的 NDK

安裝 NDK

首先到下載頁面下載 NDK 套件,並且解壓縮到適合的資料夾

打開local.properties,設定 NDK 的路徑,如下圖

設定NDK路徑

打開

設定 useDeprecatedNdk

然後在 main 資料夾下建立 JNI Folder,如下圖

建立 JNI Folder

在 JNI 資料夾裡面建立 Android.mk 檔案

建立 JNI Folder

在裡面輸入

1
2
3
4
5
6
7
8
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := MyLib
LOCAL_SRC_FILES := main.c

include $(BUILD_SHARED_LIBRARY)

其中 LOCAL_MODULE 是要在 Java code 裡面使用的名稱

LOCAL_SRC_FILES是要編譯的檔案

如果有多個檔案要編譯

第一個檔案要用 “:=”

後面的檔案都要用 “+=”

接著在 JNI 資料夾裡面建立 Application.mk 檔案

在裡面輸入

1
APP_ABI := armeabi-v7a

接著打開 build.gradle 檔案

建立 JNI Folder

在 defaultConfig 裡面輸入

1
2
3
ndk{
moduleName "MyLib"
}

接著在 JNI 資料夾裡面建立 main.c 檔案

並在裡面輸入

1
2
3
4
5
#include <jni.h>

Java_com_example_name_test_MainActivity_HelloFromJni(JNIEnv *env,jobject thiz){
return (*env)->NewStringUTF(env,"Hello From JNI");
}

這段意思是回傳”Hello From JNI”字串

接著回到專案的 MainActivity.java 檔

在裡面指定 lib 路徑

1
2
3
static{
System.loadLibrary("MyLib");
}

接著宣告 public native String HelloFromJni();

以下是 MainActivity.java 的程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MainActivity extends Activity {

static{
System.loadLibrary("MyLib");
}

public native String HelloFromJni();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("MainActivity","Log from Jni = " + HelloFromJni());
}

}

以下是執行結果

執行結果

安裝 openCV

安裝完 NDK 後,接著是安裝 openCV

首先先去下載頁面下載 OpenCV for Android,並且解壓縮到適合的資料夾

接著到 File -> New -> Import Module 引入 sdk\java,命名為 opencv-java

Import Module

接著到 opencv-java 裡面打開 build.gradle 檔案

修改裡面的 sdk version,不然編譯會有問題

修改 sdk version

打開在 build.gradle 檔案,在裡面加入

1
2
3
4
5
6
7
8
9
10
11
12
13
sourceSets.main {
jni.srcDirs = [] //disable automatic ndk-build call
}
task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
commandLine "C:\\android-ndk-r10e\\ndk-build.cmd",
'NDK_PROJECT_PATH=build\\intermediates\\ndk',
'NDK_LIBS_OUT=src\\main\\jniLibs',
'APP_BUILD_SCRIPT=src\\main\\jni\\Android.mk',
'NDK_APPLICATION_MK=src\\main\\jni\\Application.mk'
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}

修改 build.gradle

接著到剛剛的 Android.mk 檔案加入以下指令

1
2
3
4
5
6
OPENCVROOT := C:\OpenCV-2.4.9-android-sdk
OPENCV_INSTALL_MODULES := on
OPENCV_LIB_TYPE := SHARED
include ${OPENCVROOT}\sdk\native\jni\OpenCV.mk

LOCAL_LDLIBS += -llog

打開 Application.mk 檔案加入以下指令

1
2
3
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_PLATFORM := android-23

接著就可以編譯 opencv 的檔案了

參考

  1. [Android] 4-4 在Android Studio使用JNI
  2. NDK_OpenCV_AndroidStudio