在 flutter
中能夠經過 method channel
的方式來調用 opencv api
,那麼就會有較長的調用鏈flutter -> java jni -> c++
。html
假如咱們要傳遞一個參數,這個參數將會在 java、C++
堆各拷貝一次,這樣容易形成內存抖動,且效率較低。java
本文將講述如何在 flutter android
項目中接入 opencv sdk
,經過 FFI 調用 opencv c++ api
來實現高斯模糊效果。android
版本提示: Dart 2.12.0 版本以後 (同時包含在 Flutter 2.0 和之後的版本里), FFI 已經做爲穩定版本發佈。c++
Flutter
移動版可使用 dart:ffi
庫來調用本地的 C API
。 FFI
表明 外部功能接口。相似功能的其餘術語包括本地接口和語言綁定。api
您必須首先確保本地代碼已加載,而且其符號對 Dart
可見,而後才能在庫或程序使用 FFI
庫綁定本地代碼。markdown
Open Cv 下載地址app
解壓後包含如下內容:ide
建立一個 flutter
插件名爲opencv_plugin
,在 main
目錄下新建 cpp
目錄。oop
建立 native-lib.cpp
文件在 cpp
目錄下。post
複製 OpenCv
的 include
文件到 cpp
目錄下。
indlue
文件在sdk -> native -> jni -> include
新建 jniLibs
文件,並複製 libs
到 jniLibs
indlue
文件在sdk -> native -> libs
複製完成後的目錄:
新建 CmakeLists.txt
到 Android
目錄下,內容以下:
cmake_minimum_required(VERSION 3.4.1)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
add_library(libopencv_java4 SHARED IMPORTED)
set_target_properties(libopencv_java4 PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/libs/${ANDROID_ABI}/libopencv_java4.so)
add_library( # Sets the name of the library.
native-lib # Sets the library as a shared library.
SHARED # Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib # Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib libopencv_java4 # Links the target library to the log library
android
# included in the NDK.
${log-lib} )
複製代碼
CmakeLists.txt
文件位置:
注:
include_directories
與set_target_properties
必定要使用${CMAKE_SOURCE_DIR}
配置絕對路徑,否則編譯過程當中會報找不到.so
的問題。
將 opencv_plugin
下的 Gradle
文件添加一下內容
c++_shared.so
庫CmakeLists.txt
路徑android {
compileSdkVersion 30
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
minSdkVersion 16
### 引入 c++_shared.so 庫
externalNativeBuild {
cmake {
cppFlags ""
arguments "-DANDROID_STL=c++_shared"
}
}
}
### 配置 CmakeLists.txt 路徑
externalNativeBuild {
cmake {
path file('CMakeLists.txt')
}
}
}
複製代碼
在 flutter
調用 DynamicLibrary.open("libnative-lib.so")
觀察日誌是否報錯。
final DynamicLibrary _opencvLib =
Platform.isAndroid ? DynamicLibrary.open("libnative-lib.so") : DynamicLibrary.process();
複製代碼