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:\soft\OpenCV-android-sdk\sdk\native\jni\OpenCV.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 = []
  }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值