【Android】Android Studio 2上利用NDK进行OpenCV 3.1开发(注意点)

来源:互联网 发布:java script else 编辑:程序博客网 时间:2024/06/15 21:44


【参考】Android Studio 2上利用NDK进行OpenCV 3.1开发

                OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)

                [安卓开发笔记一]Android开发配置opencv环境超详细教程


开发环境

        Windows 7 x64 旗舰版

        Android Studio 2.1.2

        JDK 1.8.0————(C:\Program Files\Java\jdk1.8.0_102)

        Android 6.0(API 23)

        OpenCV 3.1.0 Android SDK————(E:\Android-Config\OpenCV-android-sdk\sdk\native\jni)

        Android NDK r12b————————(E:\Android-Config\android-ndk-r12b)


1、打开Android Studio 2.1.2,点击sdk_manager_button图标打开SDK Manager。选择SDK Tools,勾选NDK如下图


我是另外下载,解压到上面“开发环境”的路径。


2、打开Android Studio,新建一个项目;(参考一)

File——Project Structure

--Android SDK Location:C:\Users\duan\AppData\Local\Android\Sdk

--JDK Location:C:\Program Files\Java\jdk1.8.0_102

--Android NDK Location:E:\Android-Config\android-ndk-r12b   (重要)

3、右键main,新建jni——在源码目录创建一个jni文件夹。右击main文件夹,选择New->Directory,输入jni;

再新建Android.mk,Application.mk,gray-process.cpp




4、此时项目的文件结构如下图所示,比较重要的文件用红色框标记:



5、每个文件的内容:

MainActivity:

grayProc()、loadLibrary();

package com.example.duanjiwei.opencvndk;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Bitmap.Config;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;public class MainActivity extends AppCompatActivity implements OnClickListener {    private Button btnProc;    private ImageView imageView;    private Bitmap bmp;    public static native int[] grayProc(int[] pixels, int w, int h);    static {        System.loadLibrary("gray-process");    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btnProc = (Button) findViewById(R.id.btn_gray_process);        imageView = (ImageView) findViewById(R.id.image_view);        bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic);        imageView.setImageBitmap(bmp);        btnProc.setOnClickListener(this);    }    @Override    public void onClick(View v) {        int w = bmp.getWidth();        int h = bmp.getHeight();        int[] pixels = new int[w*h];        bmp.getPixels(pixels, 0, w, 0, 0, w, h);        int[] resultInt = grayProc(pixels, w, h);        Bitmap resultImg = Bitmap.createBitmap(w, h, Config.ARGB_8888);        resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);        imageView.setImageBitmap(resultImg);    }    @Override    public void onResume(){        super.onResume();    }}
activity_main.xml

添加Button、ImageView控件

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.duanjiwei.opencvndk.MainActivity">    <Button        android:id="@+id/btn_gray_process"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="@string/str_proc"/>    <ImageView        android:id="@+id/image_view"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:contentDescription="@string/str_proc"        android:layout_marginTop="60dp"        android:layout_centerHorizontal="true" /></RelativeLayout>

Android.mk

注意:OpenCV路径,使用 “/” 做分隔; 使用"\\"出现错误;

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)#opencvinclude E:/Android-Config/OpenCV-android-sdk/sdk/native/jni/OpenCV.mkOPENCV_CAMERA_MODULES:=onOPENCV_INSTALL_MODULES:=onOPENCV_LIB_TYPE:=SHAREDLOCAL_SRC_FILES := gray-process.cppLOCAL_LDLIBS += -llogLOCAL_MODULE := gray-processinclude $(BUILD_SHARED_LIBRARY)
Application.mk

APP_ABI中添加适用范围;

APP_STL := gnustl_sharedAPP_CPPFLAGS := -frtti -fexceptions -std=c++11APP_ABI := armeabi armeabi-v7a x86APP_PLATFORM := android-15

gray_process.cpp

.cpp文件中编写C++代码;Android中关于JNI 的学习(一)对于JNIEnv的一些认识

那么C++和Java之间的是如何通过JNI来进行互相调用的呢?
我们知道,在Android中,当Java文件被编译成dex文件之后,会由类加载器加载到Dalvik VM(DVM)中,由DVM来进行解释,翻译成机器语言之后,才能由机器来运行。
而对于C/C++来说,其源代码经由Android提供的NDK工具包,可以编译成可执行动态库(即.so文件),之后,Java和C++之间就可以进行通讯了。

jni.h源文件:http://blog.csdn.net/taily_duan/article/details/52488783

//// Created by duanjiwei on 2016/9/8.//#include <jni.h>#include <opencv2/opencv.hpp>extern "C" {using namespace cv;using namespace std;JNIEXPORT jintArray JNICALL Java_com_example_duanjiwei_opencvndk_MainActivity_grayProc(JNIEnv *env, jclass obj, jintArray buf, jint w, jint h){    jboolean ptfalse = false;    jint* srcBuf = env->GetIntArrayElements(buf, &ptfalse);    if(srcBuf == NULL){        return 0;    }    int size=w * h;    Mat srcImage(h, w, CV_8UC4, (unsigned char*)srcBuf);    Mat grayImage;    cvtColor(srcImage, grayImage, COLOR_BGRA2GRAY);    cvtColor(grayImage, srcImage, COLOR_GRAY2BGRA);    jintArray result = env->NewIntArray(size);    env->SetIntArrayRegion(result, 0, size, srcBuf);    env->ReleaseIntArrayElements(buf, srcBuf, 0);    return result;}}
res--values--strings.xml

<resources>    <string name="app_name">OpenCVNDK</string>    <string name="str_proc">gray process</string>    <string name="str_desc">image description</string></resources>
src下的build.gradle

import org.apache.tools.ant.taskdefs.condition.Osapply plugin: 'com.android.application'android {    compileSdkVersion 23    buildToolsVersion "23.0.3"    defaultConfig {        applicationId "com.example.duanjiwei.opencvndk"        minSdkVersion 15        targetSdkVersion 23        versionCode 1        versionName "1.0"    }    sourceSets.main {        jniLibs.srcDirs = ['src/main/libs', 'src/main/jniLibs']        jni.srcDirs = [] //disable automatic ndk-build call    }    project.ext.versionCodes = ['armeabi':1, 'armeabi-v7a':2, 'arm64-v8a':3, 'mips':5, 'mips64':6, 'x86':8, 'x86_64':9]    //versionCode digit for each supported ABI, with 64bit>32bit and x86>armeabi-*    android.applicationVariants.all { variant ->        // assign different version code for each output        variant.outputs.each { output ->            output.versionCodeOverride =                    project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + defaultConfig.versionCode        }    }    // call regular ndk-build(.cmd) script from app directory    task ndkBuild(type: Exec) {        Properties properties = new Properties()        properties.load(project.rootProject.file('local.properties').newDataInputStream())        def ndkDir = properties.getProperty('ndk.dir')        if (Os.isFamily(Os.FAMILY_WINDOWS)) {            commandLine "$ndkDir/ndk-build.cmd", '-C', file('src/main/jni').absolutePath        } else {            commandLine "$ndkDir/ndk-build", '-C', file('src/main/jni').absolutePath        }    }    tasks.withType(JavaCompile) {        compileTask -> compileTask.dependsOn ndkBuild    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:23.3.0'}
app下的build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {    repositories {        jcenter()    }    dependencies {        classpath 'com.android.tools.build:gradle:2.1.2'        // NOTE: Do not place your application dependencies here; they belong        // in the individual module build.gradle files    }}allprojects {    repositories {        jcenter()    }}task clean(type: Delete) {    delete rootProject.buildDir}


local.properties

Android sdk路径、NDK路径;

## This file is automatically generated by Android Studio.# Do not modify this file -- YOUR CHANGES WILL BE ERASED!## This file should *NOT* be checked into Version Control Systems,# as it contains information specific to your local configuration.## Location of the SDK. This is only used by Gradle.# For customization when using a Version Control System, please read the# header note.sdk.dir=C\:\\Users\\duanjiwei\\AppData\\Local\\Android\\Sdkndk.dir=E\:\\Android-Config\\android-ndk-r12b


模拟器与手机上均能成功运行:




===================================================

网上Q群方法:

 先import module
添加依赖 


 app中创jniLibs 


 sourceSets改成这样 










2 0
原创粉丝点击