代码过程实现

AndroidStudio平台JNI对Opencv环境搭建请参考文章 https://blog.csdn.net/u014159143/article/details/88975487

平台开发环境

  • Android Studio 3.2
  • opencv-3.4.3-android-sdk

配置文件修改

1、将opencv和app的build.gradle中配置改成一致:

compileSdkVersion 28minSdkVersion 17targetSdkVersion 28

2、修改openCVLibrary343\src\main\AndroidManifest.xml文件中的配置(根据你的需要修改)

<?xml version="1.0" encoding="utf-8"?>    

3、在app的build.gradle文件中指定jnilib目录

android {    compileSdkVersion 28    defaultConfig {        ... ...        externalNativeBuild {            cmake {                cppFlags "-std=c++11 -frtti -fexceptions"            }        }    }    ... ...    externalNativeBuild {        cmake {            path "CMakeLists.txt"        }    }    sourceSets{        main{            jniLibs.srcDirs = ['libs']        }    }}

4、在CMakeLists.txt文件中添加opencv的库配置

cmake_minimum_required(VERSION 3.4.1)# 添加opencv的头文件目录include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)# 导入opencv的soadd_library(opencv_java3 SHARED IMPORTED)set_target_properties(opencv_java3 PROPERTIES IMPORTED_LOCATION        ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libopencv_java3.so)... ...target_link_libraries( # Specifies the target library.        native-lib opencv_java3        # Links the target library to the log library        # included in the NDK.        ${log-lib})

千万注意:以上代码中的三个库名称可以写成opencv_java3、libopencv_java3、mylib等等,这里我先前纠结了很久,主要是发现网上有写成opencv_java3的也有写成libopencv_java3的,后来我查了下cmake的原理才明白, 它的原理就是将你调用的库重新编译成一个文件,当然编译成的名字还是libopencv_java3.so(你可以对比下apk中的so库和libs下的已经不一样了),叫啥名字无所谓,只是方便jni编译和调用而已,但是一定要一致,否则将报错。

好了如果AS没有报错误,恭喜你,你的平台环境已经搭建完成,现在只需要修改代码就可实现你想要的功能了,这里我们还是用网上比较多的图片二值化效果:

编写功能代码

1、编写布局文件layout.xml

首先将你要用的图片拖进来:

编写你的布局文件:

<?xml version="1.0" encoding="utf-8"?>        

2、编写MainActivity.java代码

package com.hello;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.ImageView;import android.widget.TextView;import org.opencv.core.Mat;public class MainActivity extends AppCompatActivity {    // Used to load the 'native-lib' library on application startup.    static {        System.loadLibrary("opencv_java3");        System.loadLibrary("native-lib");    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ImageView ivOld = (ImageView)findViewById(R.id.ivOld);        ImageView ivNew = (ImageView)findViewById(R.id.ivNew);        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.luffy);        int width = bitmap.getWidth();        int height = bitmap.getHeight();        int[] pixArr = new int[width*height];        bitmap.getPixels(pixArr,0,width,0,0,width,height);        gray(pixArr,width,height);        Bitmap newBitmap = Bitmap.createBitmap(width,height,Bitmap.Config.RGB_565);        newBitmap.setPixels(pixArr,0,width,0,0,width,height);        ivNew.setImageBitmap(newBitmap);    }    /**     * A native method that is implemented by the 'native-lib' native library,     * which is packaged with this application.     */    public native String stringFromJNI();    public native int[] gray(int [] pix,int w,int h);}

说明一下,这里的gray函数是我想添加的native函数,教大家一个快速生成jni接口的方法:将光标放在gray上,按住Alt+Enter,选择Create fuction将自动生成Jni接口函数,怎么样帅不帅,还傻傻的自己写或者javac编译么,哈哈,智能改变工作。

还有一点需要说明的是System.loadlibrary(opencv_java3),在高版本android设备上是不需要的,但是如果低版本就必须写上,而且是在调用opencv_java3的jni库前面写,具体原因不知道,这是我在调试android4.2版本的时候遇到的,都是血与泪的教训啊。

3、编写native-lib.cpp

#include #include #include #include #include #include using namespace cv;extern "C" JNIEXPORT jstring JNICALLJava_com_test_MainActivity_stringFromJNI(        JNIEnv *env,        jobject /* this */) {    std::string hello = "Hello from C++";    return env->NewStringUTF(hello.c_str());}extern "C"JNIEXPORT jintArray JNICALLJava_com_test_MainActivity_gray(JNIEnv *env, jobject instance, jintArray pix_, jint w, jint h) {    jint *pix = env->GetIntArrayElements(pix_, NULL);    if (pix == NULL) {        return 0;    }#if 1    //将c++图片转成Opencv图片    Mat imgData(h, w, CV_8UC4, (unsigned char *) pix);    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;    }#endif    int size = w * h;    jintArray result = env->NewIntArray(size);    env->SetIntArrayRegion(result, 0, size, pix);    env->ReleaseIntArrayElements(pix_, pix, 0);    return result;}

切记一定要加上opencv2/opencv.hpp和using namespace cv;

好了到这里已经全部完成了。下面来看看效果:

如果还有问题的话可以参考我的代码:点我下载

更多相关文章

  1. android中打开本地doc、pdf、ppt、text等文件功能的实现
  2. Android封装BaseActivity
  3. android音乐播放器怎么搜索SD卡上的音乐文件
  4. Android读取手机文件列表
  5. android刷字体教程
  6. 【WEB服务器】i-jetty环境搭配与编译 .
  7. 在Android中修改快捷方式的图标
  8. Android-常用代码-36片段
  9. 常用的 Android(安卓)Studio 快捷键

随机推荐

  1. android基础知识12:android自动化测试04—
  2. Ubuntu中useradd和adduser的区别
  3. 15、Android之Adapter用法总结
  4. Android知识体系总结之Android部分之通知
  5. Android(安卓)图片库Glide - Glide3.x 官
  6. Android安装器学习笔记(一)
  7. Android 尺寸单位转换和屏幕适配相关
  8. 2011.07.14——— android res与assets的
  9. Android(安卓)Q之提前适配攻略(五)(存储权限
  10. Android 屏幕适配:最全面的解决方案