android jni处理图片,Android Studio JNI层调用OpenCV进行图像处理

This article was written on 2018-03-28,may have been out of date ,just for reference.

Android调用OpenCV的Android SDK进行计算机视觉相关的开发,可以调用JAVA层的函数,也可以直接调用JNI层的方法。前者需要在手机上另外安装Android Opencv Manager,并且apk体积也会增大,所以不推荐,后者可以只编译出需要用到的函数的.so库,apk只需要引用这个.so库,所以apk体积不会太大。所以推荐使用opencv的native方法进行jni编程并编译.so库。

本机环境

Win10_x64

Android Studio 3.1

OpenCV3.4.1

准备工作

下载opencv3.4.1

相关配置

最开始,先配置添加外部工具,因为JNI编程需要经常用到,每次cd到目录然后手打javah等命令是一件很没有效率的事情,在文件->设置->工具->外部工具中点击+号新建External Tools

我们需要添加3个工具

Name:

javah(SDK23)

Program:

JDKPath\bin\javah.exe

Arguments:

-d ModuleFileDir\src\main\jni -classpath D:\ProgramData\Android\SDK\platforms\android-23\android.jar;. FileClass

Working directory:

ModuleFileDir\src\main\java

Name:

ndk-build(module)

Program:

D:\ProgramData\Android\SDK\ndk-bundle\build\ndk-build.cmd

Working directory:

ProjectFileDir\ModuleName\src\main

Name:

ndk-build clean(module)

在ndk-build(module)基础上增加一个clean参数即可

Program:

D:\ProgramData\Android\SDK\ndk-bundle\build\ndk-build.cmd

Arguments:

clean

Working directory:

ProjectFileDir\ModuleName\src\main

以后只要在mudule目录中右键然后找到External Tools,点击即可使用这些命令。

一个示例

为了便于扩展,我们创建一个新的module,你可以取名为opencv3,我自己原先取的ImageProcLib举例就不改了。

首先在工程中创建ImageProcLib module,里面包含一个工具类ImageProcUtils,这样,我们在app module中的Activity中就可以调用ImageProcLib module中的工具类中的本地方法。

ImageProcUtils示例:

package cn.gloud.imageproclib;

import android.graphics.Bitmap;

import android.util.Log;

public class ImageProcUtils {

private static final String TAG = "ImageProcUtils";

static {

//导入生成的链接库文件

System.loadLibrary("ImageProcUtils");

}

public boolean ImageMatchTempl(int x, int y, Bitmap imageBitmap, Bitmap templBitmap, int threshold) {

return ImageMatchTemplate(x,y,imageBitmap,templBitmap,threshold);

}

//本地方法,模板匹配

private native boolean ImageMatchTemplate(int x, int y, Bitmap imageBitmap, Bitmap templBitmap, int threshold);

}

在module的 src\main下创建一个文件夹命名为jni

因为我们不需要java层函数,所以只复制...\OpenCV-android-sdk\sdk下的native文件夹到刚才创建的jni目录下即可

配置build.gradle,下面是module的build.gradle文件的模板

apply plugin: 'com.android.library'

android {

...

defaultConfig {

...

//配置NDK信息

ndk {

moduleName "ImageProcUtils"

ldLibs "log", "jnigraphics", "m", "z"

abiFilters "armeabi-v7a","x86" //,"x86"等架构

}

//配置SO文件存放路径

sourceSets {

main {

jni.srcDirs = []

jniLibs.srcDirs = ['src/main/libs']

}

}

}

//设置构建脚本路径,会自动索引同目录下的Application.mk

externalNativeBuild {

ndkBuild {

path 'src/main/jni/Android.mk'

}

}

//如果报错More than one file was found with OS independent path时添加

packagingOptions {

pickFirst 'lib/armeabi-v7a/libImageProcUtils.so'

}

...

}

dependencies {

implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation 'com.android.support:appcompat-v7:23.4.0'

...

}

利用javah命令编译ImageProcUtils的头文件于jni目录下,例如cn_gloud_imageproclib_ImageProcUtils.h,如果你配置好了外部工具,只需要右键ImageProcUtils,在External Tools中点击javah工具即可,

复制cn_gloud_imageproclib_ImageProcUtils.h到同目录下修改后缀名为.cpp,例如cn_gloud_imageproclib_ImageProcUtils.cpp

.cpp需要进一步修改,示例:

#include

#include

#include

#include

#ifndef LOG

#define TAG "ImageMatchTemplate"

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型

#endif

/*

* Class: cn_gloud_imageproclib_ImageProcUtils

* Method: ImageMatchTemplate

* Signature: (IILandroid/graphics/Bitmap;Landroid/graphics/Bitmap;I)Z

*/

JNIEXPORT jboolean JNICALL Java_cn_gloud_imageproclib_ImageProcUtils_ImageMatchTemplate

(JNIEnv *env, jobject obj, jint x, jint y, jobject imageBitmap, jobject templBitmap,jint threshold){

}

jni目录下创建Android.mk和Application.mk文件

Android.mk:

LOCAL_PATH:=(call my-dir) include (CLEAR_VARS)

OPENCV_LIB_TYPE :=STATIC #利用静态库编译

ifeq ("(wildcard (OPENCV_MK_PATH))","")

include (LOCAL_PATH)/native/jni/OpenCV.mk else include (OPENCV_MK_PATH)

endif

LOCAL_MODULE := ImageProcUtils #和System.loadLibrary("ImageProcUtils");中指定的一样

LOCAL_LDLIBS += -llog -ljnigraphics #相关依赖库

LOCAL_SRC_FILES := cn_gloud_imageproclib_ImageProcUtils.cpp #源文件

include (BUILD_SHARED_LIBRARY) #编译动态库 #LOCAL_SRC_FILES := libImageProcUtils.so #预编译则指定so库 #include (PREBUILT_SHARED_LIBRARY) #预编译动态库

Application.mk:

APP_STL := gnustl_static #STL库

APP_CPPFLAGS := -frtti -fexceptions #编译参数

APP_PLATFORM := android-21 #android平台

APP_ABI += armeabi-v7a x86 #cpu架构

右键jni目录点击外部工具的ndk-build(module)就可以编译生成工具类需要的.so库了,.so库会生成在jni目录下的libs目录中,目录在build.gradle中指定

app module引用ImageProcLib module,修改app的build.gradle

dependencies {

...

implementation project(path: ':ImageProcLib')

}

修改工程的settings.gradle,

include ':app', ':ImageProcLib'

你可能感兴趣的:(android,jni处理图片)