其实网上关于 AndroidStudio使用CMake编译方式的NDK opencv开发 类似的博客已经有很多了,但是为什么我还要去写这篇博客呢,因为我在引用OpenCV库时踩了很多坑,所以特别记录一下。
搭建步骤:
一.创建AS支持C++的工程
File------>New-------------->New Project
项目结构
创建jniLibs
src------>main------>jinLibs
复制OpenCV-android-sdk\sdk\native\libs放在jinLibs目录下 opencv-3.4.1-android-sdk下载地址
解压后文件目录:
CMakeLists.txt配置
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
#工程路径
set(pathToProject E:/openCV/TestCpp)
# 支持 -std=gnu++11
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
# CMAKE_SOURCE_DIR 是 CMakeLists.txt 所在的目录
#CPP文件夹下带编译的cpp文件
add_library( native-lib SHARED src/main/cpp/native-lib.cpp)
#OpenCV-android-sdk路径
set(pathToOpenCV E:/openCV/opencv-3.4.2-android-sdk/OpenCV-android-sdk)
#配置加载native依赖
include_directories( ${pathToOpenCV}/sdk/native/jni/include )
#动态方式加载opencv的动态库
add_library(libopencv SHARED IMPORTED)
#引入libopencv_java3.so文件
set_target_properties(libopencv PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/libs/${ANDROID_ABI}/libopencv_java3.so)
#C++日志
find_library(log-lib log )
target_link_libraries( native-lib ${log-lib} libopencv )
build.gradle配置
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.administrator.testcpp"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
}
ndk{
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs/libs']
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
MainActivity应用
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
System.loadLibrary("opencv_java3");
}
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
imageView = this.findViewById(R.id.imageView);
tv.setText(stringFromJNI());
this.findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
grayPic();
}
});
}
private void grayPic(){
Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.card);
int w = bmp.getWidth();
int h = bmp.getHeight();
int[] pixels = new int[w*h];
bmp.getPixels(pixels, 0, w, 0, 0, w, h);
//recall JNI
int[] resultInt =getGrayImag(pixels, w, h);
Bitmap resultImg = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);
imageView.setImageBitmap(resultImg);
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
/**
* 获取处理的图片
* @return
* @param pixels
* @param w
* @param h
*/
public native int [] getGrayImag(int[] pixels, int w, int h);
@Override
protected void onResume() {
super.onResume();
}
}
native-lib.cpp
#include <jni.h>
#include <string>
#include <opencv2/core/hal/interface.h>
#include <opencv2/core/mat.hpp>
extern "C" JNIEXPORT jstring
JNICALL
Java_com_example_administrator_testcpp_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_example_administrator_testcpp_MainActivity_getGrayImag(JNIEnv *env, jobject instance,
jintArray pixels_, jint w, jint h) {
jint *pixels = env->GetIntArrayElements(pixels_, NULL);
// TODO
if (pixels == NULL) {
return NULL;
}
cv::Mat imgData(h, w, CV_8UC4, pixels);
uchar *ptr = imgData.ptr(0);
for (int i = 0; i < w * h; i++) {
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] = (uchar) grayScale;
ptr[4 * i + 2] = (uchar) grayScale;
ptr[4 * i + 0] = (uchar) grayScale;
}
int size = w * h;
jintArray result = env->NewIntArray(size);
env->SetIntArrayRegion(result, 0, size, pixels);
env->ReleaseIntArrayElements(pixels_, pixels, 0);
return result;
}
执行前效果图
执行后
到此结束!!!