第一个ndk-jni opencv程序

声明下,我使用的是opencv3.3.4的库,ndk15,至于为什么,看我下一篇文章。

1、环境搭建

首先要确保你的第一个ndk-jni 环境搭建成功,参考我的上一篇文章《我的第一个NDK-jni程序》,下面呢我会再给大家重新配置一次,看不懂下面配置的就看我上一篇文章https://mp.csdn.net/mdeditor/89525978#

1、下载ndk15

此时我们要用的ndk15,所以我们卸载掉as默认的最新版本,操作如下
Alt text
Alt text

然后去掉Android NDK前面的勾,点击ok就会完成卸载。

Alt text

接下来需要下载一个ndk15版本,给你们提供一个链接,里面有各个版本。
https://blog.csdn.net/shuzfan/article/details/52690554

下载完毕后需要解压文件,将解压路径设置为:Android Studio的SDK目录里,并命名为ndk-bundle。

2、取消Android studio默认NDK支持

因为我们要自己写Android.mk和Application.mk文件,所以我们要取消默认NDK支持,话不多说,看图。
Alt text
Alt text
Alt text
去掉Android NDK support前面的勾,此时Android APK support前面的勾也会自动被去掉,不用管它,去掉之后点ok,会重启。

3、添加ndk依赖目录

1、选择你的NDK目录就行了,我的只是作为参考,点击ok。
Alt text
Alt text

2、接下来gradle.properties
添加一句

android.useDeprecatedNdk=true

Alt text

3、打开local.properties
当你配置好NDK目录后,会自动生成这两句。

ndk.dir=/home/book/Android/Sdk/ndk-bundle
sdk.dir=/home/book/Android/Sdk

Alt text

2、开始编写代码

1、创建一个新的java类

Alt text

我们暂且命名为NDKUtils,内容如下:

package com.example.book.ndklinkopecv1;
public class NDKUtils {
    static {
        System.loadLibrary("OpenCV");//导入生成的链接库文件
    }
    public static native int[] grayProc(int[] pixels, int w, int h);
}

Alt text

2、生成头文件

打开目录:/src/main/java

然后输入以下代码生成头文件

javah -jni com.example.book.ndklinkopecv1.NDKUtils

注意:本目录仅供参,实际以你的目录为准。

此时就会生成一个头文件
Alt text

3、创建jni文件

此时我们需要创建一个jni文件夹,把头文件移进去。

在main目录上右键
Alt text

选择JNIFolder,生成jni文件夹。

Alt text
把头文件移动进去,并且创建一个cpp文件,直接复制就行了,后缀改一下就ok。
Alt text

4、创建Android.mk和Application.mk文件

touch 就行了,不多说。

Alt text

5、添加opencv依赖库

进入你下载的opencv(一定是android版本的),把sdk下的native文件复制到jni文件下。
Alt text

6、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 /work/h_course/android/NdklinkOPecv1/app/src/main/jni/native/jni/OpenCV.mk  //本目录仅供参考,根据自己的目录为准

else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := OpenCV  //生成依赖库的名字
LOCAL_SRC_FILES := com_example_book_ndklinkopecv1_NDKUtils.cpp //该文件下的cpp文件,名字要准确
LOCAL_LDLIBS +=  -lm -llog

LOCAL_CPP_FEATURES += exceptions
include $(BUILD_SHARED_LIBRARY)
7、Application.mk配置
APP_STL += gnustl_static //ndk16版本及以上用c++_static 
APP_CPPFLAGS += -frtti -fexceptions
APP_PLATFORM := android-16
8、cpp文件内容
#include <jni.h>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "com_example_book_ndklinkopecv1_NDKUtils.h"
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

extern "C" {
JNIEXPORT jintArray JNICALL Java_com_example_book_ndklinkopecv1_NDKUtils_grayProc
  (JNIEnv *env, jclass 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;
  }
}
9、MainActivity文件
package com.example.book.ndklinkopecv1;

import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        NDKUtils ndk = new NDKUtils();
        Bitmap bitmap;

        bitmap = ((BitmapDrawable) getResources().getDrawable(
                R.drawable.h1)).getBitmap(); //在drawble文件下导入图片为h1

        int w = bitmap.getWidth(), h = bitmap.getHeight();
        int[] pix = new int[w * h];
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);

        int [] resultPixes=NDKUtils.grayProc(pix,w,h);
        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.imageView);
        img.setImageBitmap(result);
    }
}
10、配置界面
<ImageView
  android:id="@+id/imageView"
   android:layout_width="377dp"
   android:layout_height="wrap_content"
   tools:layout_editor_absoluteX="0dp"
   tools:layout_editor_absoluteY="0dp" />

>界面自行脑补
11、ndk-build编译生成依赖库

进入jni文件,ndk-build编译,编译成功后会生成库文件
Alt text

这一步你可能会遇到很多坑,但是不要怕,静下心,方法总比困难多,该栽的跟头一个都不会少,这样你才会进步。你可以去我的下一篇文章中找答案,或者去度娘。

12、运行

如果你的ndk版本、opencv版本和我的一样,两个mk文件配置正确,ndk-build通过,那么运行是没有问题的,如果遇到问题,请看下一篇文章。

到此结束。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值