Для проекта, над которым я работаю, мне удалось создать плагин флаттера, который использует OpenCV для обработки изображений, поступающих с камеры. Помните, что когда я говорю « с камеры », я имею в виду не кадры реального времени из захвата видео, а изображения, ранее сохраненные в памяти устройства.
Прежде всего, я следовал документам Flutter относительно создания плагинов здесь
Когда flutter создал папку и файлы плагина, я получил структуру, похожую на эту (папка "opencv" на первом уровне является корнем плагина):
![Folder structure](https://i.stack.imgur.com/PTxub.png)
Обратите внимание на файл opencv-341.jar
, который я добавил и содержит методы Java для управления собственными библиотеками, OpenCVPlugin.java
и opencv.dart
, которые являются точкой входа для доступа к методам Java из Flutter и были созданы из Flutter.
Имена файлов .java и .dart могут отличаться и отражать имя, переданное вами в качестве аргумента на этапе создания плагина выше.
Файл .jar можно найти в пакете OpenCV для JAVA в виде предварительно скомпилированной библиотеки. В этом же пакете вы найдете нативные библиотеки, необходимые в конце этого маленького обличия.
Файл build.gradle
в [plugin_root] / android должен ссылаться на файл jar следующим образом
dependencies {
implementation files('opencv/opencv-341.jar')
}
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
.
Чтобы разрешить эту часть, единственный способ, который я основал к настоящему времени, - это скопировать нативные библиотеки в ваш окончательный проект, как этот (это корень вашего приложения, а не плагин):
![enter image description here](https://i.stack.imgur.com/zIv8f.png)
Я включил финальную нативную библиотеку .so для каждой платформы, на которую я хочу ориентироваться, поэтому независимо от того, на какой платформе есть пользователь, код всегда может подобрать правильный .so и правильно загрузить OpenCV.
СОВЕТ: Поскольку включение всех .so файлов может привести к большому APK, я предлагаю вам настроить build.gradle, чтобы разделить пакет на abis, таким образом у вас будет меньший apk, который будет автоматически обслуживаться через Play Store.