• studio 配置 opencv3.1


    环境

    win10

    android studio2.0

    OpenCV-3.1.0-android-sdk

    android-ndk-r10e-windows-x86_64

    jdk-8u102-windows-x64



    1配置ndk环境

    补充,这里注意把ndk的环境变量补上,目录设置为ndk的根目录就ok,主要是用来使用ndk-build



    2 新建JNI目录

    先单选工程目录,然后再点File,否则没那么多选项,找不到创建目录选项

    默认生成在app/src/main/jni/


    3 在jni中加入Application.mk和Android.mk

    Application.mk

    APP_STL := gnustl_static                                       //标准c++ stl库
    APP_CPPFLAGS := -frtti -fexceptions
    APP_ABI := armeabi armeabi-v7a                                 //还可以添加x86等
    APP_PLATFORM := android-23                                     //可以不写

    Android.mk

    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)
    
    OpenCV_INSTALL_MODULES := on
    OpenCV_CAMERA_MODULES := off
    
    OPENCV_LIB_TYPE :=STATIC//使用静态库
    
    ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
    include D:softOpenCV-android-sdksdk
    ativejniOpenCV.mk//这个路径配自己的
    else
    include $(OPENCV_MK_PATH)
    endif
    
    LOCAL_MODULE := OpenCV   //打包so的名称,实际名称是libOpenCV.so  加载时只需要加载OpenCV.so
    
    LOCAL_SRC_FILES := com_n_topencv_OpencvUtils.cpp//要放进so的cpp
    
    LOCAL_LDLIBS +=  -lm -llog
    
    include $(BUILD_SHARED_LIBRARY)

    说明:
    
    

    如果有多个放入so的cpp

    可以按如下写法
    
    

    LOCAL_SRC_FILES := 
    	playercore-jni.cpp 
    	libplayer.cpp 
    	event.cpp 
    	lock.cpp 
    	receiver.cpp 
    	decoder.cpp 
    	render.cpp 
    	androidaudio.cpp 
    	androidvideo.cpp 
    	blit.cpp 
    	yuv2rgbv7.S


    4 工程配置

    app下的build.gradle

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"
    
        defaultConfig {
            applicationId "com.n.topencv"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
    
            //ndk{
            //    moduleName "OpenCV"         //生成的so名字
            //    abiFilters "armeabi", "armeabi-v7a"  //输出指定三种abi体系结构下的so库。目前可有可无。
            //}
    
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    
        sourceSets {
            main() {
                jniLibs.srcDirs =  ['src/main/libs','src/main/jniLibs']       //把jni库指定为中括号中地址(原地址src/main/jniLibs)默认ndk-build生成so位置为libs
                jni.srcDirs = []                                             //这个如果不设置,.h文件会提示找不到jni.h(这个文件在java sdk的include中)
            }
    
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.2.1'
    }
    

    gradle.properties (补充,之后下载的gradle没这个文件,在gradle/wrapper/下只有gradle-wrapper.properties)

    添加一句,这句是使用旧版ndk,否则使用的是实验版构建方式(实验版- -!你懂的)

    android.useDeprecatedNdk=true



    local.properties

    sdk.dir=D:\soft\Android\sdk
    ndk.dir=D:\soft\android-ndk-r10e


    5 添加java代码


    MainActivity

    package com.n.topencv;
    
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.drawable.BitmapDrawable;
    import android.media.Image;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Gravity;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Log.e("nafio","OnCreate");
            OpencvUtils opencv = new OpencvUtils();
            Log.e("nafio","InitSo");
    
            ImageView img = new ImageView(this);
            Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(
                    R.mipmap.ic_launcher)).getBitmap();
            int w = bitmap.getWidth(), h = bitmap.getHeight();
            int[] pix = new int[w * h];
            bitmap.getPixels(pix, 0, w, 0, 0, w, h);
            Log.e("nafio","befor opencv!");
            int [] resultPixes=opencv.gray(pix,w,h);
            Log.e("nafio","after opencv!");
            Bitmap result = Bitmap.createBitmap(w,h, Bitmap.Config.RGB_565);
            result.setPixels(resultPixes, 0, w, 0, 0,w, h);
    
            //ImageView img = (ImageView) findViewById(R.id.myImageView);
            if(null!=img)img.setImageBitmap(result);
            else{
                Log.e("nafio","null fuck!");
            }
            setContentView(img);
    
        }
    
    
    
    }
    


    OpencvUtils
    package com.n.topencv;
    
    /**
     * Created by cuizheng on 2016/8/1.
     */
    public class OpencvUtils {
        static {
            System.loadLibrary("OpenCV");   //defaultConfig.ndk.moduleName
        }
    
        public native int[] gray(int[] pix,int w,int h);
    }


    xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.n.topencv">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>



    6 添加jni c++代码

    com_n_topencv_OpencvUtils.h

    这个文件可以自动生成

    写完OpencvUtils.java(里面包含有native方法)这个类后,build一下工程,会在

    下生成OpencvUtils.class

    Terminal进入这个debug文件夹 执行javah -jni com.n.topencv.OpencvUtils

    执行成功会在debug下生成com_n_topencv_OpencvUtils.h,把这个头文件copy到jni中

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_n_topencv_OpencvUtils */
    
    #ifndef _Included_com_n_topencv_OpencvUtils
    #define _Included_com_n_topencv_OpencvUtils
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_n_topencv_OpencvUtils
     * Method:    gray
     * Signature: ([III)[I
     */
    JNIEXPORT jintArray JNICALL Java_com_n_topencv_OpencvUtils_gray
      (JNIEnv *, jobject, jintArray, jint, jint);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    


    com_n_topencv_OpencvUtils.cpp
    //
    // Created by cuizheng on 2016/8/1.
    //
    
    #include "com_n_topencv_OpencvUtils.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    
    extern "C" {
    
    JNIEXPORT jintArray JNICALL Java_com_n_topencv_OpencvUtils_gray(
            JNIEnv *env, jobject obj, jintArray buf, int w, int h);
    
    
    
    JNIEXPORT jintArray JNICALL Java_com_n_topencv_OpencvUtils_gray(
            JNIEnv *env, jobject obj, jintArray buf, int w, int h) {
    
        jint *cbuf;
        cbuf = env->GetIntArrayElements(buf, JNI_FALSE );
        if (cbuf == NULL) {
            return 0;
        }
    
        Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);
    
        uchar* ptr = imgData.ptr(0);
        for(int i = 0; i < w*h; i ++){
            //计算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B
            //对于一个int四字节,其彩色值存储方式为:BGRA
            int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
            ptr[4*i+1] = grayScale;
            ptr[4*i+2] = grayScale;
            ptr[4*i+0] = grayScale;
        }
    
        int size = w * h;
        jintArray result = env->NewIntArray(size);
        env->SetIntArrayRegion(result, 0, size, cbuf);
        env->ReleaseIntArrayElements(buf, cbuf, 0);
        return result;
    }
    }

    问题说明,这两个文件打开android studio会一直提示,就算点了Sync Now也没用,还是这个提示,不用管,不影响打包和运行



    7 用ndk-build打包so

    Terminal进入jni文件夹

    执行ndk-build,如果执行成功会生成如下文件夹



    说明:一旦so包打出来了,jni文件夹就可有可无了,都不影响程序运行


    8 运行


    一些常见错误报错说明

    Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.
    需要在gradle.properties中添加android.useDeprecateNdk = true;使用旧版的ndk功能(不添加会使用实验性的ndk构建工具)



    android studio上写c++头文件,引入jni.h时发现报红,cannot find jni.h

    解决方法在app->build.gradle中,android标签中

    sourceSets {
            main() {
                jni.srcDirs = [];
            }
    
        }


    Error: Your project contains C++ files but it is not using a supported native build system

    这个问题解决方法跟上面类似

    gradle.properties中加
    Android.useDeprecatedNdk=true

    build.gradle(Module:app)中加
    sourceSets {
      main {
            jni.srcDirs = []
      }
    }

  • 相关阅读:
    数组的push()、pop()、shift()和unshift()方法
    Javascript的函数柯里化
    开闭原则
    字符串相等的判断
    String类常用的方法
    阅读API文档
    String类和常量池
    String基础
    内部类的分类
    内部类的概念
  • 原文地址:https://www.cnblogs.com/nafio/p/9137289.html
Copyright © 2020-2023  润新知