6.7.0 - Alpha2 - 修复 images 部分相关方法可能引发内存泄露的问题 (issue #372)
This commit is contained in:
@@ -11,17 +11,18 @@
|
|||||||
"使用 XML 语法将 JavaScript 表达式作为属性值时, this 对象可能出现指向错误的问题",
|
"使用 XML 语法将 JavaScript 表达式作为属性值时, this 对象可能出现指向错误的问题",
|
||||||
"调用 images.requestScreenCapture 时用户取消授权可能导致应用崩溃的问题",
|
"调用 images.requestScreenCapture 时用户取消授权可能导致应用崩溃的问题",
|
||||||
"images 部分相关方法出现异常时 oneShot 标记功能失效的问题 _[`issue #372`](http://issues.autojs6.com/372)_",
|
"images 部分相关方法出现异常时 oneShot 标记功能失效的问题 _[`issue #372`](http://issues.autojs6.com/372)_",
|
||||||
|
"images 部分相关方法可能引发内存泄露的问题 _[`issue #372`](http://issues.autojs6.com/372)_",
|
||||||
"Android 10 UiObject#child 方法可能出现 ArrayIndexOutOfBoundsException 异常的问题 _[`issue #416`](http://issues.autojs6.com/416)_",
|
"Android 10 UiObject#child 方法可能出现 ArrayIndexOutOfBoundsException 异常的问题 _[`issue #416`](http://issues.autojs6.com/416)_",
|
||||||
"打包应用无法正常使用 Paddle OCR 与 Rapid OCR 功能的问题",
|
"打包应用无法正常使用 Paddle OCR 与 Rapid OCR 功能的问题",
|
||||||
"版本历史页面部分系统因字体差别导致统计数据显示不完整的问题",
|
"版本历史页面部分系统因字体差别导致统计数据显示不完整的问题",
|
||||||
"ErrorDialogActivity 可能无法正常启动的问题 _[`issue #414`](http://issues.autojs6.com/414)_ _[`issue #340`](http://issues.autojs6.com/340#issuecomment-2973485826)_",
|
"ErrorDialogActivity 可能无法正常启动的问题 _[`issue #414`](http://issues.autojs6.com/414)_ _[`issue #340`](http://issues.autojs6.com/340#issuecomment-2973485826)_",
|
||||||
"错误报告页面复制详细信息功能失效的问题"
|
"崩溃报告页面复制详细信息功能失效的问题"
|
||||||
],
|
],
|
||||||
"improvement": [
|
"improvement": [
|
||||||
"http 模块相关方法支持不安全选项参数 (isInsecure/insecure), 用于忽略证书相关异常 _[`issue #417`](http://issues.autojs6.com/417)_",
|
"http 模块相关方法支持不安全选项参数 (isInsecure/insecure), 用于忽略证书相关异常 _[`issue #417`](http://issues.autojs6.com/417)_",
|
||||||
"android.graphics.Paint#setColor 支持正常解析 ColorInt/ColorHex/ColorName 等颜色参数",
|
"android.graphics.Paint#setColor 支持正常解析 ColorInt/ColorHex/ColorName 等颜色参数",
|
||||||
"内置模块相关方法实参类型的异常消息增加类型摘要信息",
|
"内置模块相关方法实参类型的异常消息增加类型摘要信息",
|
||||||
"错误报告页面支持双指缩放调整字体大小并添加常用功能按钮"
|
"崩溃报告页面支持双指缩放调整字体大小并添加常用功能按钮"
|
||||||
],
|
],
|
||||||
"dependency": [
|
"dependency": [
|
||||||
"附加 Androidx Core (KTX) 版本 1.16.0",
|
"附加 Androidx Core (KTX) 版本 1.16.0",
|
||||||
|
|||||||
@@ -290,8 +290,8 @@
|
|||||||
android:name="org.autojs.autojs.ui.settings.DeveloperOptionsActivity"
|
android:name="org.autojs.autojs.ui.settings.DeveloperOptionsActivity"
|
||||||
android:theme="@style/AppTheme.Settings" />
|
android:theme="@style/AppTheme.Settings" />
|
||||||
|
|
||||||
<!-- <activity android:name="org.autojs.autojs.ui.error.ErrorReportActivity" android:process=":crash_report"/> -->
|
<!-- <activity android:name="org.autojs.autojs.ui.error.CrashReportActivity" android:process=":crash_report"/> -->
|
||||||
<activity android:name="org.autojs.autojs.ui.error.ErrorReportActivity" />
|
<activity android:name="org.autojs.autojs.ui.error.CrashReportActivity" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.autojs.autojs.external.tasker.TaskerScriptEditActivity"
|
android:name="org.autojs.autojs.external.tasker.TaskerScriptEditActivity"
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import org.autojs.autojs.pluginclient.DevPluginService
|
|||||||
import org.autojs.autojs.timing.TimedTaskManager
|
import org.autojs.autojs.timing.TimedTaskManager
|
||||||
import org.autojs.autojs.timing.TimedTaskScheduler
|
import org.autojs.autojs.timing.TimedTaskScheduler
|
||||||
import org.autojs.autojs.tool.CrashHandler
|
import org.autojs.autojs.tool.CrashHandler
|
||||||
import org.autojs.autojs.ui.error.ErrorReportActivity
|
import org.autojs.autojs.ui.error.CrashReportActivity
|
||||||
import org.autojs.autojs.ui.floating.FloatyWindowManger
|
import org.autojs.autojs.ui.floating.FloatyWindowManger
|
||||||
import org.autojs.autojs.util.ViewUtils
|
import org.autojs.autojs.util.ViewUtils
|
||||||
import org.autojs.autojs6.BuildConfig
|
import org.autojs.autojs6.BuildConfig
|
||||||
@@ -89,7 +89,7 @@ class App : MultiDexApplication() {
|
|||||||
|
|
||||||
private fun setUpDebugEnvironment() {
|
private fun setUpDebugEnvironment() {
|
||||||
Bugly.isDev = false
|
Bugly.isDev = false
|
||||||
val crashHandler = CrashHandler(ErrorReportActivity::class.java)
|
val crashHandler = CrashHandler(CrashReportActivity::class.java)
|
||||||
|
|
||||||
val strategy = CrashReport.UserStrategy(applicationContext)
|
val strategy = CrashReport.UserStrategy(applicationContext)
|
||||||
strategy.setCrashHandleCallback(crashHandler)
|
strategy.setCrashHandleCallback(crashHandler)
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
package org.autojs.autojs.core.cleaner;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.autojs.autojs.core.ref.MonitorResource;
|
|
||||||
import org.autojs.autojs.core.ref.NativeObjectReference;
|
|
||||||
|
|
||||||
import java.lang.ref.ReferenceQueue;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by SuperMonster003 on Dec 22, 2023.
|
|
||||||
*/
|
|
||||||
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 22, 2023.
|
|
||||||
public final class Cleaner {
|
|
||||||
|
|
||||||
public static final Cleaner instance = new Cleaner();
|
|
||||||
public static final AtomicInteger pointer = new AtomicInteger();
|
|
||||||
public static final ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
Executors.newFixedThreadPool(1).execute(() -> {
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
NativeObjectReference<?> nativeObjectReference = (NativeObjectReference<?>) Cleaner.referenceQueue.remove();
|
|
||||||
if (nativeObjectReference == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
instance.cleanup(nativeObjectReference);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
/* Ignored. */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanup(NativeObjectReference<?> nativeObjectReference) {
|
|
||||||
try {
|
|
||||||
pointer.decrementAndGet();
|
|
||||||
RegisteredCleaners.registeredCleaners.remove(nativeObjectReference);
|
|
||||||
long pointer = nativeObjectReference.pointer;
|
|
||||||
if (pointer == 0L) return;
|
|
||||||
nativeObjectReference.cleaner.cleanup(pointer);
|
|
||||||
nativeObjectReference.pointer = 0L;
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
Log.w(Cleaner.class.getSimpleName(), "cleanup error: " + nativeObjectReference.pointer, throwable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanup(MonitorResource resource, ICleaner cleaner) {
|
|
||||||
resource.getPointer();
|
|
||||||
NativeObjectReference<MonitorResource> resourceNativeCleaner = new NativeObjectReference<>(resource, referenceQueue, cleaner);
|
|
||||||
resourceNativeCleaner.pointer = resource.getPointer();
|
|
||||||
resource.setNativeObjectReference(resourceNativeCleaner);
|
|
||||||
RegisteredCleaners.registeredCleaners.add(resourceNativeCleaner);
|
|
||||||
pointer.incrementAndGet();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package org.autojs.autojs.core.cleaner;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by SuperMonster003 on Dec 22, 2023.
|
|
||||||
*/
|
|
||||||
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 22, 2023.
|
|
||||||
public interface ICleaner {
|
|
||||||
|
|
||||||
void cleanup(final long pointer);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package org.autojs.autojs.core.cleaner;
|
|
||||||
|
|
||||||
import org.autojs.autojs.core.ref.MonitorResource;
|
|
||||||
import org.autojs.autojs.core.ref.NativeObjectReference;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by SuperMonster003 on Dec 22, 2023.
|
|
||||||
*/
|
|
||||||
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 22, 2023.
|
|
||||||
public final class RegisteredCleaners {
|
|
||||||
|
|
||||||
public static final Set<NativeObjectReference<MonitorResource>> registeredCleaners = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,8 +9,6 @@ import androidx.core.graphics.get
|
|||||||
import org.autojs.autojs.annotation.ScriptInterface
|
import org.autojs.autojs.annotation.ScriptInterface
|
||||||
import org.autojs.autojs.core.opencv.Mat
|
import org.autojs.autojs.core.opencv.Mat
|
||||||
import org.autojs.autojs.core.opencv.OpenCVHelper
|
import org.autojs.autojs.core.opencv.OpenCVHelper
|
||||||
import org.autojs.autojs.core.ref.MonitorResource
|
|
||||||
import org.autojs.autojs.core.ref.NativeObjectReference
|
|
||||||
import org.autojs.autojs.pio.UncheckedIOException
|
import org.autojs.autojs.pio.UncheckedIOException
|
||||||
import org.autojs.autojs.runtime.ScriptRuntime
|
import org.autojs.autojs.runtime.ScriptRuntime
|
||||||
import org.autojs.autojs.runtime.api.Images
|
import org.autojs.autojs.runtime.api.Images
|
||||||
@@ -24,7 +22,6 @@ import org.opencv.imgproc.Imgproc
|
|||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.concurrent.atomic.AtomicLong
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on Nov 25, 2017.
|
* Created by Stardust on Nov 25, 2017.
|
||||||
@@ -32,14 +29,14 @@ import java.util.concurrent.atomic.AtomicLong
|
|||||||
* Transformed by SuperMonster003 on May 16, 2023.
|
* Transformed by SuperMonster003 on May 16, 2023.
|
||||||
*/
|
*/
|
||||||
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 20, 2023.
|
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 20, 2023.
|
||||||
open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
open class ImageWrapper : Shootable<ImageWrapper> {
|
||||||
|
|
||||||
private var mScriptRuntime: ScriptRuntime
|
private var mScriptRuntime: ScriptRuntime
|
||||||
|
|
||||||
private var mMat: Mat? = null
|
private var mMat: Mat? = null
|
||||||
private var mBgrMat: Mat? = null
|
private var mBgrMat: Mat? = null
|
||||||
private var mBitmap: Bitmap? = null
|
private var mBitmap: Bitmap? = null
|
||||||
private var mRef: NativeObjectReference<MonitorResource>? = null
|
private var mMediaImage: Image? = null
|
||||||
private var mPlane: Image.Plane? = null
|
private var mPlane: Image.Plane? = null
|
||||||
|
|
||||||
private var mWidth = 0
|
private var mWidth = 0
|
||||||
@@ -47,12 +44,6 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
private var mIsRecycled = false
|
private var mIsRecycled = false
|
||||||
private var mIsOneShot = false
|
private var mIsOneShot = false
|
||||||
|
|
||||||
private var mId = 0L
|
|
||||||
private val mNextId = AtomicLong()
|
|
||||||
|
|
||||||
var mediaImage: Image? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
val width
|
val width
|
||||||
get() = mWidth.also { ensureNotRecycled() }
|
get() = mWidth.also { ensureNotRecycled() }
|
||||||
|
|
||||||
@@ -71,10 +62,7 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
val bitmap = createBitmap(mat.width(), mat.height()).also { mBitmap = it }
|
val bitmap = createBitmap(mat.width(), mat.height()).also { mBitmap = it }
|
||||||
Utils.matToBitmap(mat, bitmap)
|
Utils.matToBitmap(mat, bitmap)
|
||||||
} else {
|
} else {
|
||||||
val mediaImage = mediaImage
|
mMediaImage?.let { mBitmap = toBitmap(it) }
|
||||||
if (mediaImage != null) {
|
|
||||||
mBitmap = toBitmap(mediaImage)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mBitmap ?: throw Exception("Bitmap of ImageWrapper should never be null")
|
return mBitmap ?: throw Exception("Bitmap of ImageWrapper should never be null")
|
||||||
@@ -93,7 +81,7 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
Utils.bitmapToMat(bitmap, newMat)
|
Utils.bitmapToMat(bitmap, newMat)
|
||||||
return newMat
|
return newMat
|
||||||
}
|
}
|
||||||
if (mediaImage != null) {
|
if (mMediaImage != null) {
|
||||||
val plane = plane ?: throw AssertionError("Image plain is null")
|
val plane = plane ?: throw AssertionError("Image plain is null")
|
||||||
plane.buffer.position(0)
|
plane.buffer.position(0)
|
||||||
return Mat(mHeight, mWidth, CvType.CV_8UC4, plane.buffer, plane.rowStride.toLong()).also { mMat = it }
|
return Mat(mHeight, mWidth, CvType.CV_8UC4, plane.buffer, plane.rowStride.toLong()).also { mMat = it }
|
||||||
@@ -111,13 +99,12 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
private set(plane) {
|
private set(plane) {
|
||||||
mPlane = plane
|
mPlane = plane
|
||||||
}
|
}
|
||||||
get() = mPlane ?: mediaImage?.planes?.get(0)
|
get() = mPlane ?: mMediaImage?.planes?.get(0)
|
||||||
|
|
||||||
constructor(scriptRuntime: ScriptRuntime, width: Int, height: Int) : this(scriptRuntime, createBitmap(width, height))
|
constructor(scriptRuntime: ScriptRuntime, width: Int, height: Int) : this(scriptRuntime, createBitmap(width, height))
|
||||||
|
|
||||||
constructor(scriptRuntime: ScriptRuntime, bitmap: Bitmap) {
|
constructor(scriptRuntime: ScriptRuntime, bitmap: Bitmap) {
|
||||||
mScriptRuntime = scriptRuntime
|
mScriptRuntime = scriptRuntime
|
||||||
mId = mNextId.incrementAndGet()
|
|
||||||
mBitmap = bitmap.also { addToList(it) }
|
mBitmap = bitmap.also { addToList(it) }
|
||||||
mWidth = bitmap.width
|
mWidth = bitmap.width
|
||||||
mHeight = bitmap.height
|
mHeight = bitmap.height
|
||||||
@@ -125,7 +112,6 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
|
|
||||||
constructor(scriptRuntime: ScriptRuntime, mat: Mat) {
|
constructor(scriptRuntime: ScriptRuntime, mat: Mat) {
|
||||||
mScriptRuntime = scriptRuntime
|
mScriptRuntime = scriptRuntime
|
||||||
mId = mNextId.incrementAndGet()
|
|
||||||
mMat = mat.also { addToList(it) }
|
mMat = mat.also { addToList(it) }
|
||||||
mWidth = mat.cols()
|
mWidth = mat.cols()
|
||||||
mHeight = mat.rows()
|
mHeight = mat.rows()
|
||||||
@@ -133,7 +119,6 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
|
|
||||||
constructor(scriptRuntime: ScriptRuntime, mat: org.opencv.core.Mat) {
|
constructor(scriptRuntime: ScriptRuntime, mat: org.opencv.core.Mat) {
|
||||||
mScriptRuntime = scriptRuntime
|
mScriptRuntime = scriptRuntime
|
||||||
mId = mNextId.incrementAndGet()
|
|
||||||
mMat = when (mat.nativeObj != 0L) {
|
mMat = when (mat.nativeObj != 0L) {
|
||||||
true -> Mat(mat.nativeObj)
|
true -> Mat(mat.nativeObj)
|
||||||
else -> Mat(mat.rows(), mat.cols(), mat.type())
|
else -> Mat(mat.rows(), mat.cols(), mat.type())
|
||||||
@@ -144,7 +129,6 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
|
|
||||||
constructor(scriptRuntime: ScriptRuntime, bitmap: Bitmap, mat: Mat?) {
|
constructor(scriptRuntime: ScriptRuntime, bitmap: Bitmap, mat: Mat?) {
|
||||||
mScriptRuntime = scriptRuntime
|
mScriptRuntime = scriptRuntime
|
||||||
mId = mNextId.incrementAndGet()
|
|
||||||
mMat = mat?.also { addToList(it) }
|
mMat = mat?.also { addToList(it) }
|
||||||
mBitmap = bitmap.also { addToList(it) }
|
mBitmap = bitmap.also { addToList(it) }
|
||||||
mWidth = bitmap.width
|
mWidth = bitmap.width
|
||||||
@@ -153,8 +137,7 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
|
|
||||||
constructor(scriptRuntime: ScriptRuntime, mediaImage: Image) {
|
constructor(scriptRuntime: ScriptRuntime, mediaImage: Image) {
|
||||||
mScriptRuntime = scriptRuntime
|
mScriptRuntime = scriptRuntime
|
||||||
mId = mNextId.incrementAndGet()
|
mMediaImage = mediaImage.also { addToList(it) }
|
||||||
this.mediaImage = mediaImage.also { addToList(it) }
|
|
||||||
mWidth = mediaImage.width
|
mWidth = mediaImage.width
|
||||||
mHeight = mediaImage.height
|
mHeight = mediaImage.height
|
||||||
}
|
}
|
||||||
@@ -269,12 +252,10 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
OpenCVHelper.release(it)
|
OpenCVHelper.release(it)
|
||||||
mBgrMat = null
|
mBgrMat = null
|
||||||
}
|
}
|
||||||
mediaImage?.let {
|
mMediaImage?.let {
|
||||||
it.close()
|
it.close()
|
||||||
mediaImage = null
|
mMediaImage = null
|
||||||
}
|
mPlane = null
|
||||||
mRef?.let {
|
|
||||||
it.pointer = 0L
|
|
||||||
}
|
}
|
||||||
mIsRecycled = true
|
mIsRecycled = true
|
||||||
}
|
}
|
||||||
@@ -301,12 +282,6 @@ open class ImageWrapper : Shootable<ImageWrapper>, MonitorResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPointer() = mId
|
|
||||||
|
|
||||||
override fun setNativeObjectReference(reference: NativeObjectReference<MonitorResource>) {
|
|
||||||
mRef = reference
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val imageList = ArrayList<WeakReference<Any>>()
|
private val imageList = ArrayList<WeakReference<Any>>()
|
||||||
|
|||||||
@@ -158,32 +158,28 @@ public class TemplateMatching {
|
|||||||
Mat currentTemplate = getPyramidDownAtLevel(template, level);
|
Mat currentTemplate = getPyramidDownAtLevel(template, level);
|
||||||
Mat transparentMask = useTransparentMask ? createTransparentMask(currentTemplate) : null;
|
Mat transparentMask = useTransparentMask ? createTransparentMask(currentTemplate) : null;
|
||||||
|
|
||||||
boolean shouldStop;
|
// 如果在上一轮中没有匹配到图片, 则考虑是否退出匹配
|
||||||
|
if (previousMatchResult.isEmpty()) {
|
||||||
Label_Check_Should_Stop:
|
// 如果不是第一次匹配, 并且不满足shouldContinueMatching的条件, 则直接退出匹配
|
||||||
{
|
if (!isFirstMatching && !shouldContinueMatching(level, selectPyramidLevel)) {
|
||||||
// 如果在上一轮中没有匹配到图片, 则考虑是否退出匹配
|
releaseIfNeeded(src, img);
|
||||||
if (previousMatchResult.isEmpty()) {
|
releaseIfNeeded(currentTemplate, template);
|
||||||
// 如果不是第一次匹配, 并且不满足shouldContinueMatching的条件, 则直接退出匹配
|
OpenCVHelper.release(transparentMask);
|
||||||
if (!isFirstMatching && !shouldContinueMatching(level, selectPyramidLevel)) {
|
break;
|
||||||
shouldStop = true;
|
}
|
||||||
break Label_Check_Should_Stop;
|
Mat matchResult = matchTemplate(src, currentTemplate, matchingMethod, transparentMask);
|
||||||
}
|
getBestMatched(matchResult, currentTemplate, matchingMethod, weakThreshold, currentMatchResult, limit, level, null, finalMatchResult);
|
||||||
Mat matchResult = matchTemplate(src, currentTemplate, matchingMethod, transparentMask);
|
OpenCVHelper.release(matchResult);
|
||||||
getBestMatched(matchResult, currentTemplate, matchingMethod, weakThreshold, currentMatchResult, limit, level, null, finalMatchResult);
|
} else {
|
||||||
OpenCVHelper.release(matchResult);
|
for (Match match : previousMatchResult) {
|
||||||
} else {
|
// 根据上一轮的匹配点, 计算本次匹配的区域
|
||||||
for (Match match : previousMatchResult) {
|
Rect roi = getROI(match.point, src, currentTemplate);
|
||||||
// 根据上一轮的匹配点, 计算本次匹配的区域
|
Mat m = new Mat(src, roi);
|
||||||
Rect roi = getROI(match.point, src, currentTemplate);
|
Mat matchResult = matchTemplate(m, currentTemplate, matchingMethod, transparentMask);
|
||||||
Mat m = new Mat(src, roi);
|
getBestMatched(matchResult, currentTemplate, matchingMethod, weakThreshold, currentMatchResult, limit, level, roi, finalMatchResult);
|
||||||
Mat matchResult = matchTemplate(m, currentTemplate, matchingMethod, transparentMask);
|
OpenCVHelper.release(m);
|
||||||
getBestMatched(matchResult, currentTemplate, matchingMethod, weakThreshold, currentMatchResult, limit, level, roi, finalMatchResult);
|
OpenCVHelper.release(matchResult);
|
||||||
OpenCVHelper.release(m);
|
|
||||||
OpenCVHelper.release(matchResult);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
shouldStop = false;
|
|
||||||
}
|
}
|
||||||
releaseIfNeeded(src, img);
|
releaseIfNeeded(src, img);
|
||||||
releaseIfNeeded(currentTemplate, template);
|
releaseIfNeeded(currentTemplate, template);
|
||||||
@@ -191,26 +187,24 @@ public class TemplateMatching {
|
|||||||
|
|
||||||
logger.addSplit("level:" + level + ", result:" + previousMatchResult);
|
logger.addSplit("level:" + level + ", result:" + previousMatchResult);
|
||||||
|
|
||||||
if (!shouldStop) {
|
// 把满足强阈值的点找出来, 加到最终结果列表
|
||||||
// 把满足强阈值的点找出来, 加到最终结果列表
|
if (!currentMatchResult.isEmpty()) {
|
||||||
if (!currentMatchResult.isEmpty()) {
|
Iterator<Match> iterator = currentMatchResult.iterator();
|
||||||
Iterator<Match> iterator = currentMatchResult.iterator();
|
while (iterator.hasNext()) {
|
||||||
while (iterator.hasNext()) {
|
Match match = iterator.next();
|
||||||
Match match = iterator.next();
|
if (match.similarity >= strictThreshold) {
|
||||||
if (match.similarity >= strictThreshold) {
|
pyrUp(match.point, level);
|
||||||
pyrUp(match.point, level);
|
finalMatchResult.add(match);
|
||||||
finalMatchResult.add(match);
|
iterator.remove();
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 如果所有结果都满足强阈值, 则退出循环, 返回最终结果
|
|
||||||
if (currentMatchResult.isEmpty()) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
previousMatchResult = currentMatchResult;
|
// 如果所有结果都满足强阈值, 则退出循环, 返回最终结果
|
||||||
isFirstMatching = false;
|
if (currentMatchResult.isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
isFirstMatching = false;
|
||||||
|
previousMatchResult = currentMatchResult;
|
||||||
}
|
}
|
||||||
logger.addSplit("result:" + finalMatchResult);
|
logger.addSplit("result:" + finalMatchResult);
|
||||||
logger.dumpToLog();
|
logger.dumpToLog();
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
package org.autojs.autojs.core.opencv;
|
package org.autojs.autojs.core.opencv;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import org.autojs.autojs.core.cleaner.Cleaner;
|
|
||||||
import org.autojs.autojs.core.cleaner.ICleaner;
|
|
||||||
import org.autojs.autojs.core.ref.MonitorResource;
|
|
||||||
import org.autojs.autojs.core.ref.NativeObjectReference;
|
|
||||||
import org.opencv.core.CvType;
|
import org.opencv.core.CvType;
|
||||||
import org.opencv.core.Range;
|
import org.opencv.core.Range;
|
||||||
import org.opencv.core.Rect;
|
import org.opencv.core.Rect;
|
||||||
@@ -15,9 +11,7 @@ import org.opencv.imgproc.Imgproc;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class Mat extends org.opencv.core.Mat implements MonitorResource {
|
public class Mat extends org.opencv.core.Mat {
|
||||||
|
|
||||||
public static final ICleaner MAT_CLEANER = new MatCleaner(null);
|
|
||||||
|
|
||||||
private volatile boolean mReleased;
|
private volatile boolean mReleased;
|
||||||
|
|
||||||
@@ -25,95 +19,72 @@ public class Mat extends org.opencv.core.Mat implements MonitorResource {
|
|||||||
private static final Method nOnes = findMethod("n_ones", Integer.TYPE, Integer.TYPE, Integer.TYPE);
|
private static final Method nOnes = findMethod("n_ones", Integer.TYPE, Integer.TYPE, Integer.TYPE);
|
||||||
private static final Method nRelease = findMethod("n_release", Long.TYPE);
|
private static final Method nRelease = findMethod("n_release", Long.TYPE);
|
||||||
|
|
||||||
private NativeObjectReference<MonitorResource> mReference;
|
|
||||||
|
|
||||||
public Mat() {
|
public Mat() {
|
||||||
super();
|
super();
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(long addr) {
|
public Mat(long addr) {
|
||||||
super(addr);
|
super(addr);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(int rows, int cols, int type) {
|
public Mat(int rows, int cols, int type) {
|
||||||
super(rows, cols, type);
|
super(rows, cols, type);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(Size size, int type) {
|
public Mat(Size size, int type) {
|
||||||
super(size, type);
|
super(size, type);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(int rows, int cols, int type, Scalar s) {
|
public Mat(int rows, int cols, int type, Scalar s) {
|
||||||
super(rows, cols, type, s);
|
super(rows, cols, type, s);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(Size size, int type, Scalar s) {
|
public Mat(Size size, int type, Scalar s) {
|
||||||
super(size, type, s);
|
super(size, type, s);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(Mat m, Range rowRange, Range colRange) {
|
public Mat(Mat m, Range rowRange, Range colRange) {
|
||||||
super(m, rowRange, colRange);
|
super(m, rowRange, colRange);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(Mat m, Range rowRange) {
|
public Mat(Mat m, Range rowRange) {
|
||||||
super(m, rowRange);
|
super(m, rowRange);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(Mat m, Rect roi) {
|
public Mat(Mat m, Rect roi) {
|
||||||
super(m, roi);
|
super(m, roi);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(int rows, int cols, int type, ByteBuffer data) {
|
public Mat(int rows, int cols, int type, ByteBuffer data) {
|
||||||
super(rows, cols, type, data);
|
super(rows, cols, type, data);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(int rows, int cols, int type, ByteBuffer data, long step) {
|
public Mat(int rows, int cols, int type, ByteBuffer data, long step) {
|
||||||
super(rows, cols, type, data, step);
|
super(rows, cols, type, data, step);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(org.opencv.core.Mat opencvMat, Range rowRange) {
|
public Mat(org.opencv.core.Mat opencvMat, Range rowRange) {
|
||||||
super(opencvMat, rowRange);
|
super(opencvMat, rowRange);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(org.opencv.core.Mat opencvMat, Range rowRange, Range colRange) {
|
public Mat(org.opencv.core.Mat opencvMat, Range rowRange, Range colRange) {
|
||||||
super(opencvMat, rowRange, colRange);
|
super(opencvMat, rowRange, colRange);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(org.opencv.core.Mat opencvMat, Rect rect) {
|
public Mat(org.opencv.core.Mat opencvMat, Rect rect) {
|
||||||
super(opencvMat, rect);
|
super(opencvMat, rect);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(org.opencv.core.Mat opencvMat, Range[] ranges) {
|
public Mat(org.opencv.core.Mat opencvMat, Range[] ranges) {
|
||||||
super(opencvMat, ranges);
|
super(opencvMat, ranges);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(int[] sizes, int type) {
|
public Mat(int[] sizes, int type) {
|
||||||
super(sizes, type);
|
super(sizes, type);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mat(int[] sizes, int type, Scalar scalar) {
|
public Mat(int[] sizes, int type, Scalar scalar) {
|
||||||
super(sizes, type, scalar);
|
super(sizes, type, scalar);
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
Cleaner.instance.cleanup(this, MAT_CLEANER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Method findMethod(final String s, final Class<?>... array) {
|
private static Method findMethod(final String s, final Class<?>... array) {
|
||||||
@@ -179,34 +150,19 @@ public class Mat extends org.opencv.core.Mat implements MonitorResource {
|
|||||||
return nRelease;
|
return nRelease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getPointer() {
|
|
||||||
return super.nativeObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNativeObjectReference(final NativeObjectReference<MonitorResource> reference) {
|
|
||||||
mReference = reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPointerString() {
|
|
||||||
return Long.toString(super.nativeObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReleased() {
|
public boolean isReleased() {
|
||||||
return mReleased || mReference != null && mReference.pointer == 0L;
|
return mReleased;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void release() {
|
public void release() {
|
||||||
if (mReleased) return;
|
if (!mReleased) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mReleased) return;
|
if (!mReleased) {
|
||||||
mReleased = true;
|
super.release();
|
||||||
if (mReference != null) {
|
mReleased = true;
|
||||||
mReference.pointer = 0L;
|
}
|
||||||
}
|
}
|
||||||
super.release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.autojs.autojs.core.opencv;
|
|
||||||
|
|
||||||
import org.autojs.autojs.core.cleaner.ICleaner;
|
|
||||||
import org.autojs.autojs.runtime.api.Images;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by SuperMonster003 on Jan 5, 2024.
|
|
||||||
*/
|
|
||||||
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Jan 5, 2024.
|
|
||||||
public class MatCleaner implements ICleaner {
|
|
||||||
|
|
||||||
private MatCleaner() {
|
|
||||||
/* Empty body. */
|
|
||||||
}
|
|
||||||
|
|
||||||
public MatCleaner(Object object) {
|
|
||||||
this();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanup(long pointer) {
|
|
||||||
try {
|
|
||||||
Images.initOpenCvIfNeeded();
|
|
||||||
Mat.n_release().invoke(null, pointer);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,62 +1,41 @@
|
|||||||
package org.autojs.autojs.core.opencv;
|
package org.autojs.autojs.core.opencv;
|
||||||
|
|
||||||
import org.autojs.autojs.core.cleaner.Cleaner;
|
|
||||||
import org.autojs.autojs.core.ref.MonitorResource;
|
|
||||||
import org.autojs.autojs.core.ref.NativeObjectReference;
|
|
||||||
import org.opencv.core.Point;
|
import org.opencv.core.Point;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modified by SuperMonster003 as of Jan 21, 2023.
|
* Modified by SuperMonster003 as of Jan 21, 2023.
|
||||||
*/
|
*/
|
||||||
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 18, 2023.
|
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 18, 2023.
|
||||||
public class MatOfPoint extends org.opencv.core.MatOfPoint implements MonitorResource {
|
public class MatOfPoint extends org.opencv.core.MatOfPoint {
|
||||||
|
|
||||||
private volatile boolean mReleased = false;
|
private volatile boolean mReleased = false;
|
||||||
|
|
||||||
private NativeObjectReference<MonitorResource> mReference;
|
|
||||||
|
|
||||||
public MatOfPoint() {
|
public MatOfPoint() {
|
||||||
init();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatOfPoint(long l) {
|
public MatOfPoint(long l) {
|
||||||
super(l);
|
super(l);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatOfPoint(org.opencv.core.Mat mat) {
|
public MatOfPoint(org.opencv.core.Mat mat) {
|
||||||
super(mat);
|
super(mat);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatOfPoint(Point... pointArray) {
|
public MatOfPoint(Point... pointArray) {
|
||||||
super(pointArray);
|
super(pointArray);
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
Cleaner.instance.cleanup(this, Mat.MAT_CLEANER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void release() {
|
public void release() {
|
||||||
if (mReleased) return;
|
if (!mReleased) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mReleased) return;
|
if (!mReleased) {
|
||||||
mReleased = true;
|
super.release();
|
||||||
if (mReference != null) {
|
mReleased = true;
|
||||||
mReference.pointer = 0L;
|
}
|
||||||
}
|
}
|
||||||
super.release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getPointer() {
|
|
||||||
return nativeObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNativeObjectReference(NativeObjectReference<MonitorResource> reference) {
|
|
||||||
mReference = reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package org.autojs.autojs.core.ref;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by SuperMonster003 on Dec 20, 2023.
|
|
||||||
*/
|
|
||||||
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 20, 2023.
|
|
||||||
public interface MonitorResource {
|
|
||||||
|
|
||||||
long getPointer();
|
|
||||||
|
|
||||||
void setNativeObjectReference(final NativeObjectReference<MonitorResource> reference);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package org.autojs.autojs.core.ref;
|
|
||||||
|
|
||||||
import org.autojs.autojs.core.cleaner.ICleaner;
|
|
||||||
|
|
||||||
import java.lang.ref.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by SuperMonster003 on Dec 15, 2023.
|
|
||||||
*/
|
|
||||||
// @Reference to Auto.js Pro 9.3.11 by SuperMonster003 on Dec 15, 2023.
|
|
||||||
public final class NativeObjectReference<T> extends PhantomReference<T> {
|
|
||||||
|
|
||||||
public final ICleaner cleaner;
|
|
||||||
public volatile long pointer;
|
|
||||||
|
|
||||||
public NativeObjectReference(final T referent, final ReferenceQueue<? super T> referenceQueue, final ICleaner cleaner) {
|
|
||||||
super(referent, referenceQueue);
|
|
||||||
this.cleaner = cleaner;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -4,10 +4,6 @@ import android.util.Log;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import org.autojs.autojs.annotation.ScriptInterface;
|
import org.autojs.autojs.annotation.ScriptInterface;
|
||||||
import org.autojs.autojs.core.cleaner.Cleaner;
|
|
||||||
import org.autojs.autojs.core.cleaner.ICleaner;
|
|
||||||
import org.autojs.autojs.core.ref.MonitorResource;
|
|
||||||
import org.autojs.autojs.core.ref.NativeObjectReference;
|
|
||||||
import org.autojs.autojs.util.ImageUtils;
|
import org.autojs.autojs.util.ImageUtils;
|
||||||
import org.opencv.calib3d.Calib3d;
|
import org.opencv.calib3d.Calib3d;
|
||||||
import org.opencv.core.Core;
|
import org.opencv.core.Core;
|
||||||
@@ -314,11 +310,10 @@ public final class ImageFeatureMatching {
|
|||||||
* A reusable bundle of feature-extraction results for a single image.
|
* A reusable bundle of feature-extraction results for a single image.
|
||||||
* zh-CN: 单张图片的特征提取结果集合.
|
* zh-CN: 单张图片的特征提取结果集合.
|
||||||
*/
|
*/
|
||||||
public static class FeatureMatchingDescriptor implements MonitorResource {
|
public static class FeatureMatchingDescriptor {
|
||||||
|
|
||||||
private final Mat mDescriptors;
|
private final Mat mDescriptors;
|
||||||
private long mNativePtr;
|
private long mNativePtr;
|
||||||
private NativeObjectReference<MonitorResource> mRef;
|
|
||||||
private final MatOfKeyPoint mKeyPoint;
|
private final MatOfKeyPoint mKeyPoint;
|
||||||
private final MatOfPoint2f mCorners;
|
private final MatOfPoint2f mCorners;
|
||||||
|
|
||||||
@@ -344,18 +339,12 @@ public final class ImageFeatureMatching {
|
|||||||
mNativePtr = descriptors.nativeObj;
|
mNativePtr = descriptors.nativeObj;
|
||||||
mKeyPoint = keyPoint;
|
mKeyPoint = keyPoint;
|
||||||
mCorners = corners;
|
mCorners = corners;
|
||||||
Cleaner.instance.cleanup(this, SelfCleaner.INSTANCE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNativePtr() {
|
public long getNativePtr() {
|
||||||
return mNativePtr;
|
return mNativePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getPointer() {
|
|
||||||
return mNativePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MatOfKeyPoint getKeyPoint() {
|
public MatOfKeyPoint getKeyPoint() {
|
||||||
return mKeyPoint;
|
return mKeyPoint;
|
||||||
}
|
}
|
||||||
@@ -367,20 +356,12 @@ public final class ImageFeatureMatching {
|
|||||||
public void release() {
|
public void release() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mNativePtr != 0L) {
|
if (mNativePtr != 0L) {
|
||||||
SelfCleaner.INSTANCE.cleanup(mNativePtr);
|
releaseFeatureMatchingDescriptor(mNativePtr);
|
||||||
mNativePtr = 0L;
|
mNativePtr = 0L;
|
||||||
if (mRef != null) {
|
|
||||||
mRef.pointer = 0L;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNativeObjectReference(NativeObjectReference<MonitorResource> ref) {
|
|
||||||
mRef = ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNativePtr(long nativePtr) {
|
public void setNativePtr(long nativePtr) {
|
||||||
mNativePtr = nativePtr;
|
mNativePtr = nativePtr;
|
||||||
}
|
}
|
||||||
@@ -389,23 +370,6 @@ public final class ImageFeatureMatching {
|
|||||||
return mCorners;
|
return mCorners;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SelfCleaner implements ICleaner {
|
|
||||||
|
|
||||||
public static SelfCleaner INSTANCE;
|
|
||||||
|
|
||||||
static {
|
|
||||||
INSTANCE = new SelfCleaner();
|
|
||||||
}
|
|
||||||
|
|
||||||
private SelfCleaner() {
|
|
||||||
/* Empty body. */
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanup(long pointer) {
|
|
||||||
releaseFeatureMatchingDescriptor(pointer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -628,7 +628,6 @@ public class Images {
|
|||||||
throw new NullPointerException(mContext.getString(R.string.error_method_called_with_null_argument, "Images.findImage", "template"));
|
throw new NullPointerException(mContext.getString(R.string.error_method_called_with_null_argument, "Images.findImage", "template"));
|
||||||
}
|
}
|
||||||
Mat src = image.getMat();
|
Mat src = image.getMat();
|
||||||
boolean shouldReleaseMat = false;
|
|
||||||
if (rect != null) {
|
if (rect != null) {
|
||||||
if (template.getWidth() > rect.width) {
|
if (template.getWidth() > rect.width) {
|
||||||
throw new Exception(mContext.getString(R.string.error_excessive_width_for_template_n_region, template.getWidth(), rect.width));
|
throw new Exception(mContext.getString(R.string.error_excessive_width_for_template_n_region, template.getWidth(), rect.width));
|
||||||
@@ -637,7 +636,6 @@ public class Images {
|
|||||||
throw new Exception(mContext.getString(R.string.error_excessive_height_for_template_n_region, template.getHeight(), rect.height));
|
throw new Exception(mContext.getString(R.string.error_excessive_height_for_template_n_region, template.getHeight(), rect.height));
|
||||||
}
|
}
|
||||||
src = new Mat(src, rect);
|
src = new Mat(src, rect);
|
||||||
shouldReleaseMat = true;
|
|
||||||
}
|
}
|
||||||
@Nullable
|
@Nullable
|
||||||
org.opencv.core.Point point;
|
org.opencv.core.Point point;
|
||||||
@@ -645,10 +643,10 @@ public class Images {
|
|||||||
point = TemplateMatching.singleTemplateMatching(
|
point = TemplateMatching.singleTemplateMatching(
|
||||||
src,
|
src,
|
||||||
template.getMat(),
|
template.getMat(),
|
||||||
new TemplateMatching.Options(-1, weakThreshold, strictThreshold, maxLevel)
|
new TemplateMatching.Options(TemplateMatching.MATCHING_METHOD_NONE, weakThreshold, strictThreshold, maxLevel)
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
if (shouldReleaseMat) {
|
if (src != image.getMat()) {
|
||||||
OpenCVHelper.release(src);
|
OpenCVHelper.release(src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -760,14 +760,15 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun concat(scriptRuntime: ScriptRuntime, args: Array<out Any?>): ImageWrapper = ensureArgumentsLengthInRange(args, 2..3) {
|
fun concat(scriptRuntime: ScriptRuntime, args: Array<out Any?>): ImageWrapper = ensureArgumentsLengthInRange(args, 2..3) {
|
||||||
val (oA, oB, direction) = it
|
val (oA, oB, direction) = it
|
||||||
val imageA = if (oA.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oA), true))?.oneShot() else oA
|
var imageA: ImageWrapper? = null
|
||||||
require(imageA is ImageWrapper) { "Argument \"imageA\" ${imageA.jsBrief()} for images.concat must be a ImageWrapper" }
|
var imageB: ImageWrapper? = null
|
||||||
val imageB = if (oB.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oB), true))?.oneShot() else oB
|
|
||||||
require(imageB is ImageWrapper) {
|
|
||||||
imageA.shoot()
|
|
||||||
"Argument \"imageB\" ${imageB.jsBrief()} for images.concat must be a ImageWrapper"
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
|
val imageARaw = if (oA.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oA), true))?.oneShot() else oA
|
||||||
|
require(imageARaw is ImageWrapper) { "Argument \"imageA\" ${imageARaw.jsBrief()} for images.concat must be a ImageWrapper" }
|
||||||
|
imageA = imageARaw
|
||||||
|
val imageBRaw = if (oB.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oB), true))?.oneShot() else oB
|
||||||
|
require(imageBRaw is ImageWrapper) { "Argument \"imageB\" ${imageBRaw.jsBrief()} for images.concat must be a ImageWrapper" }
|
||||||
|
imageB = imageBRaw
|
||||||
initOpenCvIfNeeded()
|
initOpenCvIfNeeded()
|
||||||
ApiImages.concat(scriptRuntime, imageA, imageB, directionToGravityToConcat(direction))
|
ApiImages.concat(scriptRuntime, imageA, imageB, directionToGravityToConcat(direction))
|
||||||
} finally {
|
} finally {
|
||||||
@@ -777,48 +778,55 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun detectColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLengthInRange(args, 4..6) {
|
fun detectColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLengthInRange(args, 4..6) { argList ->
|
||||||
val (o, color, x, y, threshold, algorithm) = it
|
detectColorRhino(scriptRuntime, argList, ::detectColor.name)
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
}
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.detectColor must be a ImageWrapper" }
|
|
||||||
|
@JvmStatic
|
||||||
|
fun detectColorRhino(scriptRuntime: ScriptRuntime, args: Array<out Any?>, funcName: String): Boolean {
|
||||||
|
val (o, color, x, y, threshold, algorithm) = args
|
||||||
|
var imageRef: ImageWrapper? = null
|
||||||
try {
|
try {
|
||||||
|
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
||||||
|
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.detectColor must be a ImageWrapper" }
|
||||||
|
imageRef = image
|
||||||
initOpenCvIfNeeded()
|
initOpenCvIfNeeded()
|
||||||
val pixel = pixel(scriptRuntime, arrayOf(image, coerceIntNumber(x), coerceIntNumber(y)))
|
val pixel = pixel(scriptRuntime, arrayOf(image, coerceIntNumber(x), coerceIntNumber(y)))
|
||||||
ColorDetector
|
return ColorDetector
|
||||||
.get(Colors.toIntRhino(color), coerceString(algorithm, DEFAULT_COLOR_ALGORITHM), parseNumber(threshold, DEFAULT_COLOR_THRESHOLD))
|
.get(Colors.toIntRhino(color), coerceString(algorithm, DEFAULT_COLOR_ALGORITHM), parseNumber(threshold, DEFAULT_COLOR_THRESHOLD))
|
||||||
.detectColor(Colors.redRhino(pixel).roundToInt(), Colors.greenRhino(pixel).roundToInt(), Colors.blueRhino(pixel).roundToInt())
|
.detectColor(Colors.redRhino(pixel).roundToInt(), Colors.greenRhino(pixel).roundToInt(), Colors.blueRhino(pixel).roundToInt())
|
||||||
} finally {
|
} finally {
|
||||||
image.shoot()
|
ApiImages.shoot(imageRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("detectColor(image, color, x, y, threshold, algorithm)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("detectColor(image, color, x, y, threshold, algorithm)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun detectsColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLengthInRange(args, 4..6) {
|
fun detectsColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLengthInRange(args, 4..6) { argList ->
|
||||||
val (o) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
detectColorRhino(scriptRuntime, argList, ::detectsColor.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.detectsColor must be a ImageWrapper" }
|
|
||||||
try {
|
|
||||||
initOpenCvIfNeeded()
|
|
||||||
detectColor(scriptRuntime, it)
|
|
||||||
} finally {
|
|
||||||
image.shoot()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Reference to module __images__.js from Auto.js Pro 9.3.11 by SuperMonster003 on May 10, 2025.
|
// @Reference to module __images__.js from Auto.js Pro 9.3.11 by SuperMonster003 on May 10, 2025.
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun detectMultiColors(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLengthInRange(args, 5..6) {
|
fun detectMultiColors(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLengthInRange(args, 5..6) { argList ->
|
||||||
val (o, x, y, firstColor, paths, options) = it
|
detectMultiColorsRhino(scriptRuntime, argList, ::detectMultiColors.name)
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
}
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.detectMultiColors must be a ImageWrapper" }
|
|
||||||
|
@JvmStatic
|
||||||
|
fun detectMultiColorsRhino(scriptRuntime: ScriptRuntime, args: Array<out Any?>, funcName: String): Boolean {
|
||||||
|
val (o, x, y, firstColor, paths, options) = args
|
||||||
|
var imageRef: ImageWrapper? = null
|
||||||
try {
|
try {
|
||||||
|
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
||||||
|
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.detectMultiColors must be a ImageWrapper" }
|
||||||
|
imageRef = image
|
||||||
require(paths is NativeArray) { "Argument \"paths\" ${paths.jsBrief()} for images.detectMultiColors must be a JavaScript Array" }
|
require(paths is NativeArray) { "Argument \"paths\" ${paths.jsBrief()} for images.detectMultiColors must be a JavaScript Array" }
|
||||||
initOpenCvIfNeeded()
|
initOpenCvIfNeeded()
|
||||||
val opt = options as? NativeObject ?: newNativeObject()
|
val opt = options as? NativeObject ?: newNativeObject()
|
||||||
scriptRuntime.images.colorFinder.detectMultiColors(
|
return scriptRuntime.images.colorFinder.detectMultiColors(
|
||||||
image,
|
image,
|
||||||
coerceIntNumber(x),
|
coerceIntNumber(x),
|
||||||
coerceIntNumber(y),
|
coerceIntNumber(y),
|
||||||
@@ -831,133 +839,140 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
}.toIntArray(),
|
}.toIntArray(),
|
||||||
)
|
)
|
||||||
} finally {
|
} finally {
|
||||||
image.shoot()
|
ApiImages.shoot(imageRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("detectMultiColors(image, x, y, firstColor, paths, options)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("detectMultiColors(image, x, y, firstColor, paths, options)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun detectsMultiColors(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLengthInRange(args, 5..6) {
|
fun detectsMultiColors(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLengthInRange(args, 5..6) { argList ->
|
||||||
val (o, _, _, _, paths) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
detectMultiColorsRhino(scriptRuntime, argList, ::detectsMultiColors.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.detectMultiColors must be a ImageWrapper" }
|
|
||||||
try {
|
|
||||||
require(paths is NativeArray) { "Argument \"paths\" ${paths.jsBrief()} for images.detectMultiColors must be a JavaScript Array" }
|
|
||||||
initOpenCvIfNeeded()
|
|
||||||
detectMultiColors(scriptRuntime, it)
|
|
||||||
} finally {
|
|
||||||
image.shoot()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findPointByColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) { argList ->
|
fun findPointByColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) { argList ->
|
||||||
val (o, color, xOrOptions, y, width, height, threshold) = argList
|
findPointByColorRhino(scriptRuntime, argList, ::findPointByColor.name)
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
}
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findPointByColor must be a ImageWrapper" }
|
|
||||||
|
@JvmStatic
|
||||||
|
fun findPointByColorRhino(scriptRuntime: ScriptRuntime, args: Array<out Any?>, funcName: String, overriddenThreshold: Int? = null): OpencvPoint? {
|
||||||
|
val (o, color, xOrOptions, y, width, height, threshold) = args
|
||||||
|
var imageRef: ImageWrapper? = null
|
||||||
try {
|
try {
|
||||||
|
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
||||||
|
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findPointByColor must be a ImageWrapper" }
|
||||||
|
imageRef = image
|
||||||
initOpenCvIfNeeded()
|
initOpenCvIfNeeded()
|
||||||
val opt = when {
|
val opt = when {
|
||||||
argList.size < 3 -> newNativeObject()
|
args.size < 3 -> newNativeObject()
|
||||||
argList.size == 3 -> when {
|
args.size == 3 -> when {
|
||||||
xOrOptions.isJsNullish() -> newNativeObject()
|
xOrOptions.isJsNullish() -> newNativeObject()
|
||||||
else -> xOrOptions as? NativeObject
|
else -> xOrOptions as? NativeObject
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
scriptRuntime.images.colorFinder.findPointByColor(
|
return scriptRuntime.images.colorFinder.findPointByColor(
|
||||||
image,
|
image,
|
||||||
Colors.toIntRhino(color),
|
Colors.toIntRhino(color),
|
||||||
opt?.let { parseThreshold(it).roundToInt() } ?: coerceIntNumber(threshold, DEFAULT_COLOR_THRESHOLD),
|
overriddenThreshold ?: opt?.let { parseThreshold(it).roundToInt() } ?: coerceIntNumber(threshold, DEFAULT_COLOR_THRESHOLD),
|
||||||
buildRegionInternal(image, opt?.prop("region")?.takeUnless { it.isJsNullish() } ?: listOf(/* x = */ xOrOptions, y, width, height))
|
buildRegionInternal(image, opt?.prop("region")?.takeUnless { it.isJsNullish() } ?: listOf(/* x = */ xOrOptions, y, width, height))
|
||||||
).also { image.shoot() }
|
).also { image.shoot() }
|
||||||
} finally {
|
} finally {
|
||||||
image.shoot()
|
ApiImages.shoot(imageRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("findPointByColor(image, color, options)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("findPointByColor(image, color, options)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..3) {
|
fun findColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..3) { argList ->
|
||||||
val (o, color, options) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
findPointByColorRhino(scriptRuntime, argList, ::findColor.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findColor must be a ImageWrapper" }
|
|
||||||
findPointByColor(scriptRuntime, arrayOf(image, color, options))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("findPointByColor(image, color, options)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("findPointByColor(image, color, options)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findColorInRegion(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) {
|
fun findColorInRegion(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) { argList ->
|
||||||
val (o) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
findPointByColorRhino(scriptRuntime, argList, ::findColorInRegion.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findColorInRegion must be a ImageWrapper" }
|
|
||||||
findPointByColor(scriptRuntime, it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findPointByColorExactly(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..6) {
|
fun findPointByColorExactly(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..6) { argList ->
|
||||||
val (o) = it
|
findPointByColorExactlyRhino(scriptRuntime, argList, ::findPointByColorExactly.name)
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
}
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findPointByColorExactly must be a ImageWrapper" }
|
|
||||||
findPointByColor(scriptRuntime, it + /* threshold = */ 0)
|
@JvmStatic
|
||||||
|
fun findPointByColorExactlyRhino(scriptRuntime: ScriptRuntime, args: Array<out Any?>, funcName: String): OpencvPoint? {
|
||||||
|
return findPointByColorRhino(scriptRuntime, args, funcName, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("findPointByColorExactly(image, color, x, y, width, height)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("findPointByColorExactly(image, color, x, y, width, height)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findColorEquals(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..6) {
|
fun findColorEquals(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..6) { argList ->
|
||||||
val (o) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
findPointByColorExactlyRhino(scriptRuntime, argList, ::findColorEquals.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findColorEquals must be a ImageWrapper" }
|
|
||||||
findPointByColorExactly(scriptRuntime, it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findPointsByColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsLengthInRange(args, 2..3) {
|
fun findPointsByColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsLengthInRange(args, 2..3) { argList ->
|
||||||
val (o, color, options) = it
|
findPointsByColorRhino(scriptRuntime, argList, ::findPointsByColor.name)
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
}
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findPointsByColor must be a ImageWrapper" }
|
|
||||||
|
@JvmStatic
|
||||||
|
fun findPointsByColorRhino(scriptRuntime: ScriptRuntime, args: Array<out Any?>, funcName: String): NativeArray {
|
||||||
|
val (o, color, options) = args
|
||||||
|
var imageRef: ImageWrapper? = null
|
||||||
try {
|
try {
|
||||||
|
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
||||||
|
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findPointsByColor must be a ImageWrapper" }
|
||||||
|
imageRef = image
|
||||||
initOpenCvIfNeeded()
|
initOpenCvIfNeeded()
|
||||||
val opt = options as? NativeObject ?: newNativeObject()
|
val opt = options as? NativeObject ?: newNativeObject()
|
||||||
scriptRuntime.images.colorFinder.findPointsByColor(
|
return scriptRuntime.images.colorFinder.findPointsByColor(
|
||||||
image,
|
image,
|
||||||
Colors.toIntRhino(color),
|
Colors.toIntRhino(color),
|
||||||
parseThreshold(opt).roundToInt(),
|
parseThreshold(opt).roundToInt(),
|
||||||
opt.inquire("region") { region -> buildRegionInternal(image, region) },
|
opt.inquire("region") { region -> buildRegionInternal(image, region) },
|
||||||
).toNativeArray()
|
).toNativeArray()
|
||||||
} finally {
|
} finally {
|
||||||
image.shoot()
|
ApiImages.shoot(imageRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("findPointsByColor(image, color, options)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("findPointsByColor(image, color, options)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findAllPointsForColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsLengthInRange(args, 2..3) {
|
fun findAllPointsForColor(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsLengthInRange(args, 2..3) { argList ->
|
||||||
val (o) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
findPointsByColorRhino(scriptRuntime, argList, ::findAllPointsForColor.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findAllPointsForColor must be a ImageWrapper" }
|
|
||||||
findPointsByColor(scriptRuntime, it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findPointByColors(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 3..4) {
|
fun findPointByColors(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 3..4) { argList ->
|
||||||
val (o, firstColor, paths, options) = it
|
findPointByColorsRhino(scriptRuntime, argList, ::findPointByColors.name)
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
}
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findPointByColors must be a ImageWrapper" }
|
|
||||||
|
@JvmStatic
|
||||||
|
fun findPointByColorsRhino(scriptRuntime: ScriptRuntime, args: Array<out Any?>, funcName: String): OpencvPoint? {
|
||||||
|
val (o, firstColor, paths, options) = args
|
||||||
|
var imageRef: ImageWrapper? = null
|
||||||
try {
|
try {
|
||||||
|
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
||||||
|
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findPointByColors must be a ImageWrapper" }
|
||||||
|
imageRef = image
|
||||||
require(paths is NativeArray) { "Argument \"paths\" ${paths.jsBrief()} for images.findPointByColors must be a JavaScript Array" }
|
require(paths is NativeArray) { "Argument \"paths\" ${paths.jsBrief()} for images.findPointByColors must be a JavaScript Array" }
|
||||||
initOpenCvIfNeeded()
|
initOpenCvIfNeeded()
|
||||||
val opt = options as? NativeObject ?: newNativeObject()
|
val opt = options as? NativeObject ?: newNativeObject()
|
||||||
scriptRuntime.images.colorFinder.findPointByColors(
|
return scriptRuntime.images.colorFinder.findPointByColors(
|
||||||
image,
|
image,
|
||||||
Colors.toIntRhino(firstColor),
|
Colors.toIntRhino(firstColor),
|
||||||
parseThreshold(opt).roundToInt(),
|
parseThreshold(opt).roundToInt(),
|
||||||
@@ -968,22 +983,16 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
}.toIntArray(),
|
}.toIntArray(),
|
||||||
)
|
)
|
||||||
} finally {
|
} finally {
|
||||||
image.shoot()
|
ApiImages.shoot(imageRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("findPointByColors(image, firstColor, paths, options)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("findPointByColors(image, firstColor, paths, options)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findMultiColors(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 3..4) {
|
fun findMultiColors(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 3..4) { argList ->
|
||||||
val (o, _, paths) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
findPointByColorsRhino(scriptRuntime, argList, ::findMultiColors.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findMultiColors must be a ImageWrapper" }
|
|
||||||
require(paths is NativeArray) {
|
|
||||||
image.shoot()
|
|
||||||
"Argument \"paths\" ${paths.jsBrief()} for images.findMultiColors must be a JavaScript Array"
|
|
||||||
}
|
|
||||||
findPointByColors(scriptRuntime, it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -1014,26 +1023,33 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findPointByImage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) { argList ->
|
fun findPointByImage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) { argList ->
|
||||||
val (o, template, xOrOptions, y, width, height, thresholdArg) = argList
|
findPointByImageRhino(scriptRuntime, argList, ::findPointByImage.name)
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
}
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findPointByImage must be a ImageWrapper" }
|
|
||||||
require(template is ImageWrapper) {
|
@JvmStatic
|
||||||
image.shoot()
|
fun findPointByImageRhino(scriptRuntime: ScriptRuntime, args: Array<out Any?>, funcName: String): OpencvPoint? {
|
||||||
"Argument \"template\" ${template.jsBrief()} for images.findPointByImage must be a ImageWrapper"
|
val (oA, oB, xOrOptions, y, width, height, thresholdArg) = args
|
||||||
}
|
var imageA: ImageWrapper? = null
|
||||||
|
var imageB: ImageWrapper? = null
|
||||||
try {
|
try {
|
||||||
|
val image = if (oA.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oA), true))?.oneShot() else oA
|
||||||
|
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.$funcName must be a ImageWrapper" }
|
||||||
|
imageA = image
|
||||||
|
val template = if (oB.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oB), true))?.oneShot() else oB
|
||||||
|
require(template is ImageWrapper) { "Argument \"template\" ${oB.jsBrief()} for images.$funcName must be a ImageWrapper" }
|
||||||
|
imageB = template
|
||||||
initOpenCvIfNeeded()
|
initOpenCvIfNeeded()
|
||||||
when {
|
return when {
|
||||||
argList.size > 2 && xOrOptions !is NativeObject -> {
|
args.size > 2 && xOrOptions !is NativeObject -> {
|
||||||
val options = mapOf(
|
val options = mapOf(
|
||||||
"region" to listOf(/* x = */ xOrOptions, y, width, height),
|
"region" to listOf(/* x = */ xOrOptions, y, width, height),
|
||||||
"threshold" to thresholdArg,
|
"threshold" to thresholdArg,
|
||||||
).toNativeObject()
|
).toNativeObject()
|
||||||
findPointByImage(scriptRuntime, arrayOf(image, template, options))
|
findPointByImageRhino(scriptRuntime, arrayOf(image, template, options), funcName)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val opt = when {
|
val opt = when {
|
||||||
argList.size > 2 -> xOrOptions as? NativeObject
|
args.size > 2 -> xOrOptions as? NativeObject
|
||||||
else -> null
|
else -> null
|
||||||
} ?: newNativeObject()
|
} ?: newNativeObject()
|
||||||
val weakThreshold = parseWeakThreshold(opt, 0.6).toFloat()
|
val weakThreshold = parseWeakThreshold(opt, 0.6).toFloat()
|
||||||
@@ -1044,49 +1060,39 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
ApiImages.shoot(image, template)
|
ApiImages.shoot(imageA, imageB)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("findPointByImage(image, template, options)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("findPointByImage(image, template, options)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findImage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..3) {
|
fun findImage(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) { argList ->
|
||||||
val (o, template) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
findPointByImageRhino(scriptRuntime, argList, ::findImage.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findImage must be a ImageWrapper" }
|
|
||||||
require(template is ImageWrapper) {
|
|
||||||
image.shoot()
|
|
||||||
"Argument \"template\" ${template.jsBrief()} for images.findImage must be a ImageWrapper"
|
|
||||||
}
|
|
||||||
findPointByImage(scriptRuntime, it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java", ReplaceWith("findPointByImage(image, template, x, y, width, height, threshold)"))
|
@Deprecated("Deprecated in Java", ReplaceWith("findPointByImage(image, template, x, y, width, height, threshold)"))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun findImageInRegion(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) {
|
fun findImageInRegion(scriptRuntime: ScriptRuntime, args: Array<out Any?>): OpencvPoint? = ensureArgumentsLengthInRange(args, 2..7) { argList ->
|
||||||
val (o, template) = it
|
@Suppress("DEPRECATION")
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
findPointByImageRhino(scriptRuntime, argList, ::findImageInRegion.name)
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.findImageInRegion must be a ImageWrapper" }
|
|
||||||
require(template is ImageWrapper) {
|
|
||||||
image.shoot()
|
|
||||||
"Argument \"template\" ${template.jsBrief()} for images.findImageInRegion must be a ImageWrapper"
|
|
||||||
}
|
|
||||||
findPointByImage(scriptRuntime, it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun matchTemplate(scriptRuntime: ScriptRuntime, args: Array<out Any?>): MatchingResult = ensureArgumentsLengthInRange(args, 2..3) {
|
fun matchTemplate(scriptRuntime: ScriptRuntime, args: Array<out Any?>): MatchingResult = ensureArgumentsLengthInRange(args, 2..3) {
|
||||||
val (o, template, options) = it
|
val (oA, oB, options) = it
|
||||||
val image = if (o.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(o), true))?.oneShot() else o
|
var imageA: ImageWrapper? = null
|
||||||
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.matchTemplate must be a ImageWrapper" }
|
var imageB: ImageWrapper? = null
|
||||||
require(template is ImageWrapper) {
|
|
||||||
image.shoot()
|
|
||||||
"Argument \"template\" ${template.jsBrief()} for images.matchTemplate must be a ImageWrapper"
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
|
val image = if (oA.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oA), true))?.oneShot() else oA
|
||||||
|
require(image is ImageWrapper) { "Argument \"image\" ${image.jsBrief()} for images.matchTemplate must be a ImageWrapper" }
|
||||||
|
imageA = image
|
||||||
|
val template = if (oB.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oB), true))?.oneShot() else oB
|
||||||
|
require(template is ImageWrapper) { "Argument \"template\" ${template.jsBrief()} for images.matchTemplate must be a ImageWrapper" }
|
||||||
|
imageB = template
|
||||||
initOpenCvIfNeeded()
|
initOpenCvIfNeeded()
|
||||||
val opt = options as? NativeObject ?: newNativeObject()
|
val opt = options as? NativeObject ?: newNativeObject()
|
||||||
val weakThreshold = parseWeakThreshold(opt, 0.6).toFloat()
|
val weakThreshold = parseWeakThreshold(opt, 0.6).toFloat()
|
||||||
@@ -1101,7 +1107,7 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
}
|
}
|
||||||
MatchingResult(scriptRuntime.images.matchTemplate(image, template, weakThreshold, threshold, region, level, max, useTransparentMask))
|
MatchingResult(scriptRuntime.images.matchTemplate(image, template, weakThreshold, threshold, region, level, max, useTransparentMask))
|
||||||
} finally {
|
} finally {
|
||||||
ApiImages.shoot(image, template)
|
ApiImages.shoot(imageA, imageB)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1452,17 +1458,18 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun isEqual(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLength(args, 2) { argList ->
|
fun isEqual(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsLength(args, 2) { argList ->
|
||||||
val (oA, oB) = argList
|
val (oA, oB) = argList
|
||||||
val imageA = if (oA.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oA), true))?.oneShot() else oA
|
var imageARef: ImageWrapper? = null
|
||||||
require(imageA is ImageWrapper) { "Argument \"imageA\" ${imageA.jsBrief()} for images.isEqual must be a ImageWrapper}" }
|
var imageBRef: ImageWrapper? = null
|
||||||
val imageB = if (oB.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oB), true))?.oneShot() else oB
|
|
||||||
require(imageB is ImageWrapper) {
|
|
||||||
imageA.shoot()
|
|
||||||
"Argument \"imageB\" ${imageB.jsBrief()} for images.isEqual must be a ImageWrapper"
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
|
val imageA = if (oA.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oA), true))?.oneShot() else oA
|
||||||
|
require(imageA is ImageWrapper) { "Argument \"imageA\" ${imageA.jsBrief()} for images.isEqual must be a ImageWrapper}" }
|
||||||
|
imageARef = imageA
|
||||||
|
val imageB = if (oB.isJsString()) read(scriptRuntime, arrayOf<Any>(coerceString(oB), true))?.oneShot() else oB
|
||||||
|
require(imageB is ImageWrapper) { "Argument \"imageB\" ${imageB.jsBrief()} for images.isEqual must be a ImageWrapper" }
|
||||||
|
imageBRef = imageB
|
||||||
ImageSimilarity.isEqual(imageA.mat, imageB.mat)
|
ImageSimilarity.isEqual(imageA.mat, imageB.mat)
|
||||||
} finally {
|
} finally {
|
||||||
ApiImages.shoot(imageA, imageB)
|
ApiImages.shoot(imageARef, imageBRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class CrashHandler(private val errorReportClass: Class<*>) : CrashHandleCallback
|
|||||||
if (crashTooManyTimes()) {
|
if (crashTooManyTimes()) {
|
||||||
return super.onCrashHandleStart(crashType, errorType, errorMessage, errorStack)
|
return super.onCrashHandleStart(crashType, errorType, errorMessage, errorStack)
|
||||||
}
|
}
|
||||||
startErrorReportActivity("$errorType: $errorMessage", errorStack ?: "[ No stack message ]")
|
startCrashReportActivity("$errorType: $errorMessage", errorStack ?: "[ No stack message ]")
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ class CrashHandler(private val errorReportClass: Class<*>) : CrashHandleCallback
|
|||||||
mBuglyHandler = buglyHandler
|
mBuglyHandler = buglyHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startErrorReportActivity(msg: String, detail: String) {
|
private fun startCrashReportActivity(msg: String, detail: String) {
|
||||||
Intent(GlobalAppContext.get(), errorReportClass).apply {
|
Intent(GlobalAppContext.get(), errorReportClass).apply {
|
||||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||||
putExtra("message", msg)
|
putExtra("message", msg)
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ import org.autojs.autojs6.databinding.ActivityErrorReportBinding
|
|||||||
* Created by Stardust on Feb 2, 2017.
|
* Created by Stardust on Feb 2, 2017.
|
||||||
* Transformed by SuperMonster003 on Mar 10, 2025.
|
* Transformed by SuperMonster003 on Mar 10, 2025.
|
||||||
*/
|
*/
|
||||||
class ErrorReportActivity : BaseActivity() {
|
class CrashReportActivity : BaseActivity() {
|
||||||
|
|
||||||
private lateinit var errorMessage: String
|
private lateinit var crashMessage: String
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -29,7 +29,7 @@ class ErrorReportActivity : BaseActivity() {
|
|||||||
appendLine(briefOfCurrentVersionInt(true))
|
appendLine(briefOfCurrentVersionInt(true))
|
||||||
intent.getStringExtra("message")?.let { appendLine().appendLine(it.trimEnd()) }
|
intent.getStringExtra("message")?.let { appendLine().appendLine(it.trimEnd()) }
|
||||||
intent.getStringExtra("error")?.let { appendLine().appendLine(it.trimEnd()) }
|
intent.getStringExtra("error")?.let { appendLine().appendLine(it.trimEnd()) }
|
||||||
}.also { errorMessage = it }
|
}.also { crashMessage = it }
|
||||||
|
|
||||||
val binding = ActivityErrorReportBinding.inflate(layoutInflater).also {
|
val binding = ActivityErrorReportBinding.inflate(layoutInflater).also {
|
||||||
setContentView(it.root)
|
setContentView(it.root)
|
||||||
@@ -62,7 +62,7 @@ class ErrorReportActivity : BaseActivity() {
|
|||||||
@SuppressLint("MissingSuperCall")
|
@SuppressLint("MissingSuperCall")
|
||||||
override fun onBackPressed() = exit()
|
override fun onBackPressed() = exit()
|
||||||
|
|
||||||
private fun copy() = ClipboardUtils.setClip(this, errorMessage)
|
private fun copy() = ClipboardUtils.setClip(this, crashMessage)
|
||||||
|
|
||||||
private fun exit() = finishAffinity()
|
private fun exit() = finishAffinity()
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#Sat Jun 28 19:48:58 CST 2025
|
#Tue Jul 01 00:19:56 CST 2025
|
||||||
BUILD_TIME=1751111338507
|
BUILD_TIME=1751300396808
|
||||||
COMPILE_SDK_VERSION=35
|
COMPILE_SDK_VERSION=35
|
||||||
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
||||||
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
||||||
@@ -19,6 +19,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
|
|||||||
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
||||||
TARGET_SDK_VERSION=35
|
TARGET_SDK_VERSION=35
|
||||||
TARGET_SDK_VERSION_INRT=29
|
TARGET_SDK_VERSION_INRT=29
|
||||||
VERSION_BUILD=3308
|
VERSION_BUILD=3312
|
||||||
VERSION_NAME=6.7.0 Alpha2
|
VERSION_NAME=6.7.0 Alpha2
|
||||||
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
||||||
|
|||||||
Reference in New Issue
Block a user