6.7.0 - Alpha11 - 修复 ocr.detect 异常及 ocr 部分重载方法异常
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$data": {
|
"$data": {
|
||||||
"v6.7.0": {
|
"v6.7.0": {
|
||||||
"released_date": "2025/11/02",
|
"released_date": "2025/11/19",
|
||||||
"feature": [
|
"feature": [
|
||||||
"cvt 模块, 用于数据单位转换 (参阅 项目文档 > [单位转换](https://docs.autojs6.com/#/cvt))",
|
"cvt 模块, 用于数据单位转换 (参阅 项目文档 > [单位转换](https://docs.autojs6.com/#/cvt))",
|
||||||
"fmt 模块, 用于数据格式化 (参阅 项目文档 > [格式化](https://docs.autojs6.com/#/fmt))",
|
"fmt 模块, 用于数据格式化 (参阅 项目文档 > [格式化](https://docs.autojs6.com/#/fmt))",
|
||||||
@@ -46,6 +46,8 @@
|
|||||||
"images 部分方法使用区域参数时 1 被误解析为百分比的问题",
|
"images 部分方法使用区域参数时 1 被误解析为百分比的问题",
|
||||||
"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)_",
|
"images 部分相关方法可能引发内存泄露的问题 _[`issue #372`](http://issues.autojs6.com/372)_",
|
||||||
|
"ocr 部分重载方法可能无法正常使用的问题",
|
||||||
|
"ocr.detect 方法获得的结果可能与 ocr.mode 不匹配的问题",
|
||||||
"Android 10 UiObject#child 方法可能出现 ArrayIndexOutOfBoundsException 异常的问题 _[`issue #416`](http://issues.autojs6.com/416)_",
|
"Android 10 UiObject#child 方法可能出现 ArrayIndexOutOfBoundsException 异常的问题 _[`issue #416`](http://issues.autojs6.com/416)_",
|
||||||
"运行项目时 project.json 配置参数无法正常解析的问题",
|
"运行项目时 project.json 配置参数无法正常解析的问题",
|
||||||
"项目配置文件中构建版本号或构建时间出现较大数字时可能导致应用崩溃的问题",
|
"项目配置文件中构建版本号或构建时间出现较大数字时可能导致应用崩溃的问题",
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class OcrRapid {
|
|||||||
|
|
||||||
// 创建 OcrResult 对象
|
// 创建 OcrResult 对象
|
||||||
OcrResult(
|
OcrResult(
|
||||||
label = block.text,
|
text = block.text,
|
||||||
confidence = block.boxScore,
|
confidence = block.boxScore,
|
||||||
bounds = rect,
|
bounds = rect,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ import kotlin.math.abs
|
|||||||
/**
|
/**
|
||||||
* Represents a result from Optical Character Recognition (OCR) processing.
|
* Represents a result from Optical Character Recognition (OCR) processing.
|
||||||
*
|
*
|
||||||
* @property label The recognized text label.
|
* @property text The recognized text.
|
||||||
* @property confidence The confidence score of the recognition, ranging from 0 (least confident) to 1 (most confident).
|
* @property confidence The confidence score of the recognition, ranging from 0 (least confident) to 1 (most confident).
|
||||||
* @property bounds The bounding box coordinates of the recognized text region.
|
* @property bounds The bounding box coordinates of the recognized text region.
|
||||||
*/
|
*/
|
||||||
class OcrResult(@JvmField val label: String, @JvmField val confidence: Float, @JvmField val bounds: Rect) : Comparable<OcrResult> {
|
class OcrResult(@JvmField val text: String, @JvmField val confidence: Float, @JvmField val bounds: Rect) : Comparable<OcrResult> {
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val label: String = text
|
||||||
|
|
||||||
override fun compareTo(other: OcrResult): Int {
|
override fun compareTo(other: OcrResult): Int {
|
||||||
// 上下差距小于二分之一的高度 判定为同一行
|
// 上下差距小于二分之一的高度 判定为同一行
|
||||||
@@ -27,6 +30,6 @@ class OcrResult(@JvmField val label: String, @JvmField val confidence: Float, @J
|
|||||||
|
|
||||||
override fun toString() =
|
override fun toString() =
|
||||||
"${OcrResult::class.java.simpleName}@${Integer.toHexString(hashCode())}" +
|
"${OcrResult::class.java.simpleName}@${Integer.toHexString(hashCode())}" +
|
||||||
"{label=$label, confidence=$confidence, bounds=$bounds}"
|
"{text=$text, confidence=$confidence, bounds=$bounds}"
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,23 +7,27 @@ import org.autojs.autojs.extension.AnyExtensions.isJsString
|
|||||||
import org.autojs.autojs.extension.AnyExtensions.jsBrief
|
import org.autojs.autojs.extension.AnyExtensions.jsBrief
|
||||||
import org.autojs.autojs.extension.AnyExtensions.jsSpecies
|
import org.autojs.autojs.extension.AnyExtensions.jsSpecies
|
||||||
import org.autojs.autojs.extension.ArrayExtensions.toNativeArray
|
import org.autojs.autojs.extension.ArrayExtensions.toNativeArray
|
||||||
import org.autojs.autojs.extension.ScriptableExtensions.prop
|
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
||||||
|
import org.autojs.autojs.extension.FlexibleArray.Companion.component2
|
||||||
|
import org.autojs.autojs.extension.FlexibleArray.Companion.component3
|
||||||
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
||||||
|
import org.autojs.autojs.extension.ScriptableExtensions.prop
|
||||||
|
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
|
||||||
import org.autojs.autojs.runtime.ScriptRuntime
|
import org.autojs.autojs.runtime.ScriptRuntime
|
||||||
|
import org.autojs.autojs.runtime.api.OcrResult
|
||||||
import org.autojs.autojs.runtime.api.augment.Augmentable
|
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||||
import org.autojs.autojs.runtime.api.augment.Invokable
|
import org.autojs.autojs.runtime.api.augment.Invokable
|
||||||
import org.autojs.autojs.runtime.api.augment.images.Images
|
|
||||||
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
||||||
import org.autojs.autojs.runtime.exception.ShouldNeverHappenException
|
|
||||||
import org.autojs.autojs.util.RhinoUtils
|
|
||||||
import org.autojs.autojs.util.RhinoUtils.UNDEFINED
|
import org.autojs.autojs.util.RhinoUtils.UNDEFINED
|
||||||
import org.autojs.autojs.util.RhinoUtils.newNativeArray
|
import org.autojs.autojs.util.RhinoUtils.coerceString
|
||||||
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||||
import org.mozilla.javascript.NativeArray
|
import org.mozilla.javascript.NativeArray
|
||||||
import org.mozilla.javascript.NativeObject
|
import org.mozilla.javascript.NativeObject
|
||||||
|
import org.mozilla.javascript.ScriptableObject
|
||||||
import org.mozilla.javascript.Undefined
|
import org.mozilla.javascript.Undefined
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
import kotlin.reflect.full.declaredMemberProperties
|
||||||
import android.graphics.Rect as AndroidRect
|
import android.graphics.Rect as AndroidRect
|
||||||
import org.autojs.autojs.runtime.api.augment.images.Images as AugmentableImages
|
import org.autojs.autojs.runtime.api.augment.images.Images as AugmentableImages
|
||||||
import org.opencv.core.Rect as OpencvRect
|
import org.opencv.core.Rect as OpencvRect
|
||||||
@@ -46,187 +50,25 @@ class Ocr(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime)
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
enum class OcrMode(val value: String) {
|
|
||||||
MLKIT("mlkit"),
|
|
||||||
PADDLE("paddle"),
|
|
||||||
RAPID("rapid"),
|
|
||||||
UNKNOWN("unknown")
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun tap(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsOnlyOne(args) { mode ->
|
fun tap(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Undefined = ensureArgumentsOnlyOne(args) { mode ->
|
||||||
scriptRuntime.ocr.mode = when (mode) {
|
scriptRuntime.ocr.mode = mode.toOcrModeOrNull(scriptRuntime) ?: OcrMode.MLKIT.also {
|
||||||
scriptRuntime.augmentedOcrMLKit -> OcrMode.MLKIT
|
throw WrappedIllegalArgumentException("Unknown mode ${mode.jsSpecies()} for ocr.tap")
|
||||||
scriptRuntime.augmentedOcrPaddle -> OcrMode.PADDLE
|
}
|
||||||
scriptRuntime.augmentedOcrRapid -> OcrMode.RAPID
|
|
||||||
else -> when (RhinoUtils.coerceStringLowercase(mode, "")) {
|
|
||||||
OcrMode.MLKIT.value -> OcrMode.MLKIT
|
|
||||||
OcrMode.PADDLE.value -> OcrMode.PADDLE
|
|
||||||
OcrMode.RAPID.value -> OcrMode.RAPID
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
} ?: OcrMode.MLKIT.also { throw WrappedIllegalArgumentException("Unknown mode ${mode.jsSpecies()} for ocr.tap") }
|
|
||||||
return@ensureArgumentsOnlyOne UNDEFINED
|
return@ensureArgumentsOnlyOne UNDEFINED
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun recognizeText(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
fun recognizeText(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
||||||
val (arg0, arg1, arg2) = argList
|
recognizeTextWith(scriptRuntime, null, argList)
|
||||||
|
|
||||||
when {
|
|
||||||
arg0.isJsString() -> {
|
|
||||||
|
|
||||||
// @Signature
|
|
||||||
// recognizeText(imgPath: string, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
|
|
||||||
// recognizeText(imgPath: string, region: OmniRegion): string[];
|
|
||||||
|
|
||||||
val imgPath = arg0
|
|
||||||
val img = AugmentableImages.read(scriptRuntime, arrayOf(imgPath)) ?: throw WrappedIllegalArgumentException(
|
|
||||||
"Invalid image of path \"$imgPath\" for ocr.recognizeText(img, options?)",
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Overload
|
|
||||||
// recognizeText(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
|
|
||||||
// recognizeText(img: ImageWrapper, region: OmniRegion): string[];
|
|
||||||
recognizeText(scriptRuntime, arrayOf(img.oneShot(), arg1, arg2))
|
|
||||||
}
|
|
||||||
arg0 !is ImageWrapper -> {
|
|
||||||
// @Signature
|
|
||||||
// recognizeText(options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
|
|
||||||
// recognizeText(region: OmniRegion): string[];
|
|
||||||
|
|
||||||
// @Overload
|
|
||||||
// recognizeText(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
|
|
||||||
// recognizeText(img: ImageWrapper, region: OmniRegion): string[];
|
|
||||||
|
|
||||||
val capt = AugmentableImages.captureScreen(scriptRuntime, emptyArray())
|
|
||||||
recognizeText(scriptRuntime, arrayOf(capt, arg0, arg1))
|
|
||||||
}
|
|
||||||
shouldTakenAsRegion(arg1) -> {
|
|
||||||
|
|
||||||
// @Signature recognizeText(img: ImageWrapper, region: OmniRegion): string[];
|
|
||||||
|
|
||||||
val region = arg1
|
|
||||||
val options = newNativeObject().also { o ->
|
|
||||||
o.defineProp("region", region)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Overload recognizeText(img: ImageWrapper, options: DetectOptionsMLKit | DetectOptionsPaddle): string[];
|
|
||||||
recognizeText(scriptRuntime, arrayOf(arg0, options))
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
|
|
||||||
// @Signature recognizeText(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
|
|
||||||
|
|
||||||
val img = arg0
|
|
||||||
val opt = arg1 as? NativeObject ?: newNativeObject()
|
|
||||||
when (val region = opt.prop("region")) {
|
|
||||||
null -> newNativeArray()
|
|
||||||
else -> {
|
|
||||||
var shouldShoot = false
|
|
||||||
val (image, options) = when {
|
|
||||||
region.isJsNullish() -> img to opt
|
|
||||||
else -> {
|
|
||||||
val clip = AugmentableImages.clip(scriptRuntime, arrayOf(img, region))
|
|
||||||
shouldShoot = true
|
|
||||||
clip.oneShot() to opt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val results = when (opt.prop("mode").takeIf { it is OcrMode } ?: scriptRuntime.ocr.mode) {
|
|
||||||
OcrMode.MLKIT -> OcrMLKit.recognizeTextInternal(scriptRuntime, image, options)
|
|
||||||
OcrMode.PADDLE -> OcrPaddle.recognizeTextInternal(scriptRuntime, image, options)
|
|
||||||
OcrMode.RAPID -> OcrRapid.recognizeTextInternal(scriptRuntime, image, options)
|
|
||||||
else -> throw WrappedIllegalArgumentException("Cannot call ocr.recognizeText with an unknown mode")
|
|
||||||
}
|
|
||||||
if (shouldShoot) img.shoot()
|
|
||||||
results.toNativeArray()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun detect(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
fun detect(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
||||||
val (arg0, arg1, arg2) = argList
|
detectWith(scriptRuntime, null, argList)
|
||||||
|
|
||||||
when {
|
|
||||||
arg0.isJsString() -> {
|
|
||||||
|
|
||||||
// @Signature
|
|
||||||
// detect(imgPath: string, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
// detect(imgPath: string, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
|
|
||||||
val imgPath = arg0
|
|
||||||
val img = AugmentableImages.read(scriptRuntime, arrayOf(imgPath)) ?: throw WrappedIllegalArgumentException(
|
|
||||||
"Invalid image of path \"$imgPath\" for ocr.detect(img, options?)",
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Overload
|
|
||||||
// detect(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
// detect(img: ImageWrapper, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
detect(scriptRuntime, arrayOf(img.oneShot(), arg1, arg2))
|
|
||||||
}
|
|
||||||
arg0 !is ImageWrapper -> {
|
|
||||||
// @Signature
|
|
||||||
// detect(options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
// detect(region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
|
|
||||||
// @Overload
|
|
||||||
// detect(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
// detect(img: ImageWrapper, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
|
|
||||||
val capt = AugmentableImages.captureScreen(scriptRuntime, emptyArray())
|
|
||||||
detect(scriptRuntime, arrayOf(capt, arg0, arg1))
|
|
||||||
}
|
|
||||||
shouldTakenAsRegion(arg1) -> {
|
|
||||||
|
|
||||||
// @Signature detect(img: ImageWrapper, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
|
|
||||||
val region = arg1
|
|
||||||
val options = newNativeObject().also { o ->
|
|
||||||
o.defineProp("region", region)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Overload detect(img: ImageWrapper, options: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
detect(scriptRuntime, arrayOf(arg0, options))
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
|
|
||||||
// @Signature detect(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
|
||||||
|
|
||||||
val img = arg0
|
|
||||||
val opt = arg1 as? NativeObject ?: newNativeObject()
|
|
||||||
when (val region = opt.prop("region")) {
|
|
||||||
null -> newNativeArray()
|
|
||||||
else -> {
|
|
||||||
var shouldShoot = false
|
|
||||||
val (image, options) = when {
|
|
||||||
region.isJsNullish() -> img to opt
|
|
||||||
else -> {
|
|
||||||
val clip = AugmentableImages.clip(scriptRuntime, arrayOf(img, region))
|
|
||||||
shouldShoot = true
|
|
||||||
clip.oneShot() to opt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val results = when (scriptRuntime.ocr.mode) {
|
|
||||||
OcrMode.MLKIT -> OcrMLKit.detectInternal(scriptRuntime, image, options)
|
|
||||||
OcrMode.PADDLE -> OcrPaddle.detectInternal(scriptRuntime, image, options)
|
|
||||||
OcrMode.RAPID -> OcrRapid.detectInternal(scriptRuntime, image, options)
|
|
||||||
else -> throw WrappedIllegalArgumentException("Cannot call ocr.detect with an unknown mode")
|
|
||||||
}.also {
|
|
||||||
val rect = Images.buildRegion(scriptRuntime, arrayOf(img, region))
|
|
||||||
it.forEach { result -> result.bounds.offset(rect.x, rect.y) }
|
|
||||||
}
|
|
||||||
if (shouldShoot) img.shoot()
|
|
||||||
results.toNativeArray()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("EnumValuesSoftDeprecate")
|
@Suppress("EnumValuesSoftDeprecate")
|
||||||
@@ -246,58 +88,131 @@ class Ocr(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime)
|
|||||||
summary(scriptRuntime, args)
|
summary(scriptRuntime, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun commonRecognizeText(scriptRuntime: ScriptRuntime, mode: OcrMode, vararg args: Any?): NativeArray = ensureArgumentsAtMost(args, 2) { argList ->
|
internal fun recognizeTextWith(scriptRuntime: ScriptRuntime, overrideMode: OcrMode?, unwrappedArgs: Array<out Any?>): NativeArray {
|
||||||
commonInvoker(scriptRuntime, mode, ::recognizeText, *argList)
|
return dispatchOcrWith<String>(scriptRuntime, ::recognizeText.name, unwrappedArgs, overrideMode).toNativeArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun commonDetect(scriptRuntime: ScriptRuntime, mode: OcrMode, vararg args: Any?): NativeArray = ensureArgumentsAtMost(args, 2) { argList ->
|
internal fun detectWith(scriptRuntime: ScriptRuntime, overrideMode: OcrMode?, unwrappedArgs: Array<out Any?>): NativeArray {
|
||||||
commonInvoker(scriptRuntime, mode, ::detect, *argList)
|
return dispatchOcrWith<OcrResult>(scriptRuntime, ::detect.name, unwrappedArgs, overrideMode) { results, rect ->
|
||||||
|
results.apply { forEach { it.bounds.offset(rect.x, rect.y) } }
|
||||||
|
}.toNativeArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun commonInvoker(
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
internal fun <T> dispatchOcrWith(
|
||||||
scriptRuntime: ScriptRuntime,
|
scriptRuntime: ScriptRuntime,
|
||||||
mode: OcrMode,
|
funcName: String,
|
||||||
invoker: (ScriptRuntime, Array<out Any?>) -> NativeArray,
|
unwrappedArgs: Array<out Any?>,
|
||||||
vararg args: Any?,
|
overrideMode: OcrMode? = null,
|
||||||
): NativeArray = ensureArgumentsAtMost(args, 2) { argList ->
|
resultsHandler: ((results: List<T>, rect: OpencvRect) -> List<T>)? = null,
|
||||||
val (arg0, arg1) = argList
|
): List<T> {
|
||||||
when (argList.size) {
|
val (arg0, arg1, arg2) = unwrappedArgs
|
||||||
2 -> when {
|
|
||||||
shouldTakenAsRegion(arg1) -> newNativeObject().let { options ->
|
return when {
|
||||||
options.defineProp("region", arg1)
|
arg0.isJsString() -> {
|
||||||
options.defineProp("mode", mode)
|
|
||||||
invoker(scriptRuntime, arrayOf(arg0, options))
|
// @Signature
|
||||||
}
|
// funcName(imgPath: string, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
arg1 is NativeObject -> arg1.let { options ->
|
// funcName(imgPath: string, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
options.defineProp("mode", mode)
|
|
||||||
invoker(scriptRuntime, arrayOf(arg0, options))
|
val imgPath = arg0
|
||||||
}
|
val img = AugmentableImages.read(scriptRuntime, arrayOf(imgPath)) ?: throw WrappedIllegalArgumentException(
|
||||||
else -> throw WrappedIllegalArgumentException("Unknown argument[1] ${arg1.jsBrief()} for ${mode.value}")
|
"Invalid image of path \"$imgPath\" for ocr.$funcName(img, options?)",
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Overload
|
||||||
|
// funcName(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
|
// funcName(img: ImageWrapper, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
|
dispatchOcrWith(scriptRuntime, funcName, arrayOf(img.oneShot(), arg1, arg2))
|
||||||
}
|
}
|
||||||
1 -> when {
|
arg0 !is ImageWrapper -> {
|
||||||
arg0 is NativeObject -> invoker(scriptRuntime, arrayOf(arg0.also { options ->
|
// @Signature
|
||||||
options.defineProp("mode", mode)
|
// funcName(options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
}))
|
// funcName(region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
arg0 is ImageWrapper -> invoker(scriptRuntime, arrayOf(arg0, newNativeObject().also { options ->
|
|
||||||
options.defineProp("mode", mode)
|
// @Overload
|
||||||
}))
|
// funcName(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
shouldTakenAsRegion(arg0) -> newNativeObject().let { options ->
|
// funcName(img: ImageWrapper, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
options.defineProp("region", arg0)
|
|
||||||
options.defineProp("mode", mode)
|
val capt = AugmentableImages.captureScreen(scriptRuntime, emptyArray())
|
||||||
invoker(scriptRuntime, arrayOf(arg0, options))
|
dispatchOcrWith(scriptRuntime, funcName, arrayOf(capt, arg0, arg1))
|
||||||
|
}
|
||||||
|
shouldTakenAsRegion(arg1) -> {
|
||||||
|
|
||||||
|
// @Signature funcName(img: ImageWrapper, region: OmniRegion): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
|
|
||||||
|
val region = arg1
|
||||||
|
val options = newNativeObject().also { o ->
|
||||||
|
o.defineProp("region", region)
|
||||||
}
|
}
|
||||||
else -> throw WrappedIllegalArgumentException("Unknown argument[0] ${arg0.jsBrief()} for ${mode.value}")
|
|
||||||
|
// @Overload funcName(img: ImageWrapper, options: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
|
dispatchOcrWith(scriptRuntime, funcName, arrayOf(arg0, options))
|
||||||
}
|
}
|
||||||
0 -> newNativeObject().let { options ->
|
else -> {
|
||||||
options.defineProp("mode", mode)
|
|
||||||
invoker(scriptRuntime, arrayOf(options))
|
// @Signature funcName(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
|
||||||
|
|
||||||
|
val img = arg0
|
||||||
|
val opt = arg1 as? NativeObject ?: newNativeObject()
|
||||||
|
val region = opt.prop("region") ?: return emptyList()
|
||||||
|
|
||||||
|
var shouldShoot = false
|
||||||
|
val (image, options) = when {
|
||||||
|
region.isJsNullish() -> img to opt
|
||||||
|
else -> {
|
||||||
|
val clip = AugmentableImages.clip(scriptRuntime, arrayOf(img, region))
|
||||||
|
shouldShoot = true
|
||||||
|
clip.oneShot() to opt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val optMode = overrideMode ?: opt.inquire("mode", scriptRuntime.ocr.mode)
|
||||||
|
val ocrMode = optMode.toOcrModeOrNull(scriptRuntime)
|
||||||
|
?: throw WrappedIllegalArgumentException("Cannot call ocr.$funcName with an unknown mode: ${optMode.jsBrief()}")
|
||||||
|
val prop = OcrMode::class.declaredMemberProperties.firstOrNull { it.name.contentEquals(funcName, true) }
|
||||||
|
?: throw WrappedIllegalArgumentException("Cannot find ocr dispatcher property for $funcName")
|
||||||
|
val fn = prop.get(ocrMode) as? (ScriptRuntime, ImageWrapper, NativeObject) -> List<T>
|
||||||
|
?: throw WrappedIllegalArgumentException("Dispatcher type mismatch for $funcName")
|
||||||
|
var results = fn.invoke(scriptRuntime, image, options)
|
||||||
|
resultsHandler?.let {
|
||||||
|
val rect = AugmentableImages.buildRegion(scriptRuntime, arrayOf(img, region))
|
||||||
|
results = resultsHandler(results, rect)
|
||||||
|
}
|
||||||
|
if (shouldShoot) img.shoot()
|
||||||
|
results
|
||||||
}
|
}
|
||||||
else -> throw ShouldNeverHappenException()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldTakenAsRegion(o: Any?) = o is OpencvRect || o is AndroidRect || o is NativeArray
|
private fun shouldTakenAsRegion(o: Any?) = o is OpencvRect || o is AndroidRect || o is NativeArray
|
||||||
|
|
||||||
|
private fun Any?.toOcrModeOrNull(scriptRuntime: ScriptRuntime? = null) = when (this) {
|
||||||
|
is ScriptableObject -> when (this) {
|
||||||
|
scriptRuntime?.augmentedOcrMLKit -> OcrMode.MLKIT
|
||||||
|
scriptRuntime?.augmentedOcrPaddle -> OcrMode.PADDLE
|
||||||
|
scriptRuntime?.augmentedOcrRapid -> OcrMode.RAPID
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val modeValue = coerceString(this, "")
|
||||||
|
OcrMode.entries.find { it.value.contentEquals(modeValue, true) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
private fun <T> nullImpl(scriptRuntime: ScriptRuntime, image: ImageWrapper, options: NativeObject) = emptyList<T>()
|
||||||
|
|
||||||
|
enum class OcrMode(
|
||||||
|
val value: String,
|
||||||
|
val recognizeText: ((ScriptRuntime, ImageWrapper, NativeObject) -> List<String>)?,
|
||||||
|
val detect: ((ScriptRuntime, ImageWrapper, NativeObject) -> List<OcrResult>)?,
|
||||||
|
) {
|
||||||
|
MLKIT("mlkit", OcrMLKit::recognizeTextImpl, OcrMLKit::detectImpl),
|
||||||
|
PADDLE("paddle", OcrPaddle::recognizeTextImpl, OcrPaddle::detectImpl),
|
||||||
|
RAPID("rapid", OcrRapid::recognizeTextImpl, OcrRapid::detectImpl),
|
||||||
|
UNKNOWN("unknown", ::nullImpl, ::nullImpl);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,24 +22,25 @@ class OcrMLKit(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRun
|
|||||||
|
|
||||||
override fun invoke(vararg args: Any?): NativeArray = recognizeText(scriptRuntime, args)
|
override fun invoke(vararg args: Any?): NativeArray = recognizeText(scriptRuntime, args)
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun recognizeText(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) {
|
fun recognizeText(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
||||||
Ocr.commonRecognizeText(scriptRuntime, OcrMode.MLKIT, *it)
|
Ocr.recognizeTextWith(scriptRuntime, OcrMode.MLKIT, argList)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun detect(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) {
|
fun detect(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
||||||
Ocr.commonDetect(scriptRuntime, OcrMode.MLKIT, *it)
|
Ocr.detectWith(scriptRuntime, OcrMode.MLKIT, argList)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Hint by SuperMonster003 on Nov 1, 2024.
|
// @Hint by SuperMonster003 on Nov 1, 2024.
|
||||||
// ! Reserved param `options`.
|
// ! Reserved param `options`.
|
||||||
// ! zh-CN: 预留参数 `options`.
|
// ! zh-CN: 预留参数 `options`.
|
||||||
fun recognizeTextInternal(scriptRuntime: ScriptRuntime, image: ImageWrapper, @Suppress("UNUSED_PARAMETER") options: NativeObject): List<String> {
|
fun recognizeTextImpl(scriptRuntime: ScriptRuntime, image: ImageWrapper, options: NativeObject): List<String> {
|
||||||
ApkBuilder.Libs.MLKIT_OCR.ensureLibFiles(OcrMode.MLKIT.value)
|
ApkBuilder.Libs.MLKIT_OCR.ensureLibFiles(OcrMode.MLKIT.value)
|
||||||
return scriptRuntime.ocrMLKit.recognizeText(image)
|
return scriptRuntime.ocrMLKit.recognizeText(image)
|
||||||
}
|
}
|
||||||
@@ -47,7 +48,7 @@ class OcrMLKit(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRun
|
|||||||
// @Hint by SuperMonster003 on Nov 1, 2024.
|
// @Hint by SuperMonster003 on Nov 1, 2024.
|
||||||
// ! Reserved param `options`.
|
// ! Reserved param `options`.
|
||||||
// ! zh-CN: 预留参数 `options`.
|
// ! zh-CN: 预留参数 `options`.
|
||||||
fun detectInternal(scriptRuntime: ScriptRuntime, image: ImageWrapper, @Suppress("UNUSED_PARAMETER") options: NativeObject): List<OcrResult> {
|
fun detectImpl(scriptRuntime: ScriptRuntime, image: ImageWrapper, options: NativeObject): List<OcrResult> {
|
||||||
ApkBuilder.Libs.MLKIT_OCR.ensureLibFiles(OcrMode.MLKIT.value)
|
ApkBuilder.Libs.MLKIT_OCR.ensureLibFiles(OcrMode.MLKIT.value)
|
||||||
return scriptRuntime.ocrMLKit.detect(image)
|
return scriptRuntime.ocrMLKit.detect(image)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
package org.autojs.autojs.runtime.api.augment.ocr
|
package org.autojs.autojs.runtime.api.augment.ocr
|
||||||
|
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
|
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
|
||||||
import org.autojs.autojs.apkbuilder.ApkBuilder
|
import org.autojs.autojs.apkbuilder.ApkBuilder
|
||||||
import org.autojs.autojs.core.image.ImageWrapper
|
import org.autojs.autojs.core.image.ImageWrapper
|
||||||
|
import org.autojs.autojs.core.plugin.ocr.OcrPluginHost
|
||||||
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
|
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
|
||||||
import org.autojs.autojs.runtime.ScriptRuntime
|
import org.autojs.autojs.runtime.ScriptRuntime
|
||||||
import org.autojs.autojs.runtime.api.OcrResult
|
import org.autojs.autojs.runtime.api.OcrResult
|
||||||
import org.autojs.autojs.runtime.api.augment.Augmentable
|
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||||
import org.autojs.autojs.runtime.api.augment.Invokable
|
import org.autojs.autojs.runtime.api.augment.Invokable
|
||||||
import org.autojs.autojs.runtime.api.augment.ocr.Ocr.Companion.OcrMode
|
import org.autojs.autojs.runtime.api.augment.ocr.Ocr.Companion.OcrMode
|
||||||
|
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
||||||
import org.autojs.autojs.util.RhinoUtils.coerceBoolean
|
import org.autojs.autojs.util.RhinoUtils.coerceBoolean
|
||||||
import org.autojs.autojs.util.RhinoUtils.coerceIntNumber
|
import org.autojs.autojs.util.RhinoUtils.coerceIntNumber
|
||||||
import org.mozilla.javascript.NativeArray
|
import org.mozilla.javascript.NativeArray
|
||||||
import org.mozilla.javascript.NativeObject
|
import org.mozilla.javascript.NativeObject
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
class OcrPaddle(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
class OcrPaddle(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
||||||
|
|
||||||
override val key = OcrMode.PADDLE.value
|
override val key = OcrMode.PADDLE.value
|
||||||
@@ -29,40 +33,55 @@ class OcrPaddle(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRu
|
|||||||
|
|
||||||
private const val DEFAULT_CPU_THREAD_NUM = 4
|
private const val DEFAULT_CPU_THREAD_NUM = 4
|
||||||
private const val DEFAULT_USE_SLIM = true
|
private const val DEFAULT_USE_SLIM = true
|
||||||
|
private const val DEFAULT_USE_OPENCL = false
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun recognizeText(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) {
|
fun recognizeText(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
||||||
Ocr.commonRecognizeText(scriptRuntime, OcrMode.PADDLE, *it)
|
Ocr.recognizeTextWith(scriptRuntime, OcrMode.PADDLE, argList)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun detect(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) {
|
fun detect(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
||||||
Ocr.commonDetect(scriptRuntime, OcrMode.PADDLE, *it)
|
Ocr.detectWith(scriptRuntime, OcrMode.PADDLE, argList)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun recognizeTextInternal(scriptRuntime: ScriptRuntime, image: ImageWrapper, options: NativeObject): List<String> {
|
fun recognizeTextImpl(scriptRuntime: ScriptRuntime, image: ImageWrapper, options: NativeObject): List<String> {
|
||||||
ApkBuilder.Libs.PADDLE_OCR.ensureLibFiles(OcrMode.PADDLE.value)
|
return performOcr(scriptRuntime, image, options).map {
|
||||||
val (cpuThreadNum, useSlim) = getOcrOptions(options)
|
it.text
|
||||||
return scriptRuntime.ocrPaddle.recognizeText(image, cpuThreadNum, useSlim)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun detectInternal(scriptRuntime: ScriptRuntime, image: ImageWrapper, options: NativeObject): List<OcrResult> {
|
fun detectImpl(scriptRuntime: ScriptRuntime, image: ImageWrapper, options: NativeObject): List<OcrResult> {
|
||||||
|
return performOcr(scriptRuntime, image, options).map {
|
||||||
|
OcrResult(it.text, it.confidence, it.bounds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun performOcr(scriptRuntime: ScriptRuntime, image: ImageWrapper, options: NativeObject): List<org.autojs.plugin.ocr.OcrResult> {
|
||||||
ApkBuilder.Libs.PADDLE_OCR.ensureLibFiles(OcrMode.PADDLE.value)
|
ApkBuilder.Libs.PADDLE_OCR.ensureLibFiles(OcrMode.PADDLE.value)
|
||||||
val (cpuThreadNum, useSlim) = getOcrOptions(options)
|
val (cpuThreadNum, useSlim, useOpenCL) = getOcrOptions(options)
|
||||||
return scriptRuntime.ocrPaddle.detect(image, cpuThreadNum, useSlim).map { result ->
|
val ocrOptions = org.autojs.plugin.ocr.OcrOptions().apply {
|
||||||
OcrResult(result.label, result.confidence, result.bounds)
|
this.threads = cpuThreadNum
|
||||||
|
this.useSlim = useSlim
|
||||||
|
this.useOpenCL = useOpenCL
|
||||||
|
}
|
||||||
|
return runBlocking(scriptRuntime.coroutineContext) {
|
||||||
|
val target = OcrPluginHost.select(globalContext)
|
||||||
|
?: throw WrappedIllegalArgumentException("No Paddle OCR plugin matched")
|
||||||
|
OcrPluginHost.detect(globalContext, target, image.bitmap, ocrOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOcrOptions(options: NativeObject): OcrOptions {
|
private fun getOcrOptions(options: NativeObject): OcrOptions {
|
||||||
val cpuThreadNum = options.inquire("cpuThreadNum", ::coerceIntNumber, DEFAULT_CPU_THREAD_NUM)
|
val cpuThreadNum = options.inquire("cpuThreadNum", ::coerceIntNumber, DEFAULT_CPU_THREAD_NUM)
|
||||||
val useSlim = options.inquire("useSlim", ::coerceBoolean, DEFAULT_USE_SLIM)
|
val useSlim = options.inquire("useSlim", ::coerceBoolean, DEFAULT_USE_SLIM)
|
||||||
return OcrOptions(cpuThreadNum, useSlim)
|
val useOpenCL = options.inquire("useOpenCL", ::coerceBoolean, DEFAULT_USE_OPENCL)
|
||||||
|
return OcrOptions(cpuThreadNum, useSlim, useOpenCL)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class OcrOptions(val cpuThreadNum: Int, val useSlim: Boolean)
|
private data class OcrOptions(val cpuThreadNum: Int, val useSlim: Boolean, val useOpenCL: Boolean)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,20 +26,20 @@ class OcrRapid(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRun
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun recognizeText(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) {
|
fun recognizeText(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
||||||
Ocr.commonRecognizeText(scriptRuntime, OcrMode.RAPID, *it)
|
Ocr.recognizeTextWith(scriptRuntime, OcrMode.RAPID, argList)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoRuntimeFunctionInterface
|
@RhinoRuntimeFunctionInterface
|
||||||
fun detect(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) {
|
fun detect(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeArray = ensureArgumentsAtMost(args, 3) { argList ->
|
||||||
Ocr.commonDetect(scriptRuntime, OcrMode.RAPID, *it)
|
Ocr.detectWith(scriptRuntime, OcrMode.RAPID, argList)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Hint by SuperMonster003 on Nov 1, 2024.
|
// @Hint by SuperMonster003 on Nov 1, 2024.
|
||||||
// ! Reserved param `options`.
|
// ! Reserved param `options`.
|
||||||
// ! zh-CN: 预留参数 `options`.
|
// ! zh-CN: 预留参数 `options`.
|
||||||
fun recognizeTextInternal(scriptRuntime: ScriptRuntime, image: ImageWrapper, @Suppress("UNUSED_PARAMETER") options: NativeObject): List<String> {
|
fun recognizeTextImpl(scriptRuntime: ScriptRuntime, image: ImageWrapper, @Suppress("UNUSED_PARAMETER") options: NativeObject): List<String> {
|
||||||
ApkBuilder.Libs.RAPID_OCR.ensureLibFiles(OcrMode.RAPID.value)
|
ApkBuilder.Libs.RAPID_OCR.ensureLibFiles(OcrMode.RAPID.value)
|
||||||
return scriptRuntime.ocrRapid.recognizeText(image)
|
return scriptRuntime.ocrRapid.recognizeText(image)
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ class OcrRapid(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRun
|
|||||||
// @Hint by SuperMonster003 on Nov 1, 2024.
|
// @Hint by SuperMonster003 on Nov 1, 2024.
|
||||||
// ! Reserved param `options`.
|
// ! Reserved param `options`.
|
||||||
// ! zh-CN: 预留参数 `options`.
|
// ! zh-CN: 预留参数 `options`.
|
||||||
fun detectInternal(scriptRuntime: ScriptRuntime, image: ImageWrapper, @Suppress("UNUSED_PARAMETER") options: NativeObject): List<OcrResult> {
|
fun detectImpl(scriptRuntime: ScriptRuntime, image: ImageWrapper, @Suppress("UNUSED_PARAMETER") options: NativeObject): List<OcrResult> {
|
||||||
ApkBuilder.Libs.RAPID_OCR.ensureLibFiles(OcrMode.RAPID.value)
|
ApkBuilder.Libs.RAPID_OCR.ensureLibFiles(OcrMode.RAPID.value)
|
||||||
return scriptRuntime.ocrRapid.detect(image)
|
return scriptRuntime.ocrRapid.detect(image)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user