对于我正在从事的一个项目,我成功创建了一个依赖 OpenCV 的 flutter 插件来处理来自相机的图像。请注意,当我说“从相机”,我指的不是视频捕获的实时帧,而是之前保存在设备内存中的图片。
首先,我遵循了 Flutter 文档中有关创建的内容插件在这里 https://flutter.io/docs/development/packages-and-plugins/developing-packages#developing-plugin-packages
When flutter has created the plugin folder and files, I've ended up with a structure similar to this (the "opencv" folder at first level is the root of plugin):
![Folder structure](https://i.stack.imgur.com/PTxub.png)
注意opencv-341.jar
我添加的文件包含控制本机库的 Java 方法,OpenCVPlugin.java
and opencv.dart
它们是从 Flutter 访问 Java 方法的入口点,并且是从 Flutter 创建的。
.java 和 .dart 文件的文件名可能不同,并反映您在上述插件创建阶段作为参数传递的名称。
.jar 文件可以在 JAVA 的 OpenCV 包中找到作为预编译库。在同一个包中,您将找到这个小伪装结束时所需的本机库。
The build.gradle
[plugin_root]/android 中的文件应该像这样引用 jar 文件
dependencies {
implementation files('opencv/opencv-341.jar')
}
The OpencvPlugin.java
应该托管从 dart 调用的方法。就我而言,为了更好地管理不同的方法,我创建了如下代码:
if (call.method.equals("processReceiptImage")) {
if (!call.hasArgument("input")) {
result.error("NOTFOUND", "File not found", null);
return;
}
try {
String input = call.argument("input");
int maxWidth = (int) call.argument("maxWidth");
int quality = (int) call.argument("quality");
String output = call.argument("output");
result.success(ProcessReceiptImage.run(input, maxWidth, quality, output));
return;
} catch (Exception e) {
e.printStackTrace();
result.error("UNKNOWN", e.getMessage(), null);
return;
}
}
静态方法ProcessReceiptImage
包含在相关文件中ProcessReceiptImage.java
:
package com.yourplugin.opencv;
import org.opencv.core.Mat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.util.ArrayList;
public class ProcessReceiptImage {
static String run(String input, int maxWidth, int quality, String output) throws Exception {
Mat src = Imgcodecs.imread(input, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Size size = src.size();
int height = (int) (maxWidth * size.height / size.width);
Imgproc.resize(src, src, new Size(maxWidth, height));
ArrayList<Integer> parameters;
parameters = new ArrayList();
parameters.add(Imgcodecs.CV_IMWRITE_JPEG_QUALITY);
parameters.add(quality);
MatOfInt par = new MatOfInt();
par.fromList(parameters);
Imgcodecs.imwrite(output, src, par);
return output;
}
}
从那时起,如果您运行应用程序,它可能会由于缺少库而失败opencv_java3
。
为了解决这部分问题,我现在建立的唯一方法是将本机库复制到您的最终项目中,如下所示(这是应用程序的根目录,而不是插件):
我已经为我想要定位的每个平台提供了最终的 .so 本机库,因此无论用户使用哪个平台,代码始终可以获取正确的 .so 并正确加载 OpenCV。
提示:由于包含所有 .so 文件可能会生成一个较大的 APK,因此我建议您配置 build.gradle 以便将包拆分为 abis,这样您将拥有一个较小的 apk,它将通过 Play 商店自动提供。