Files
AutoJs6/app/src/main/assets/modules/__ocr__.js

244 lines
10 KiB
JavaScript

// noinspection JSUnusedLocalSymbols
/* Overwritten protection. */
let { images } = global;
/**
* @param {ScriptRuntime} scriptRuntime
* @param {org.mozilla.javascript.Scriptable | global} scope
* @return {Internal.Ocr}
*/
module.exports = function (scriptRuntime, scope) {
let _ = {
OcrCtor: (/* @IIFE */ () => {
/**
* @type {{[modeName in Internal.Ocr.ModeName]: Internal.Ocr.ModeName}}
*/
const modeName = {
mlkit: 'mlkit',
paddle: 'paddle',
unknown: 'unknown',
};
/**
* @type {Internal.Ocr.ModeName}
*/
let _mode = modeName.unknown;
const defaultPrivateDescriptor = {
configurable: false,
writable: false,
enumerable: false,
};
const defaultProtectedDescriptor = {
configurable: false,
writable: false,
enumerable: true, /* Emphasis. */
};
const instanceFunc = function (img, options) {
if (typeof arguments[0] === 'string') {
let img = images.read(/* path = */ arguments[0]);
if (img === null) {
throw TypeError(`Invalid image of path "${arguments[0]}" for ocr(img, options?)`);
}
return OcrCtor.prototype.recognizeText(img.oneShot(), options);
}
return OcrCtor.prototype.recognizeText.apply(OcrCtor.prototype, arguments);
};
/**
* @implements Internal.Ocr
*/
const OcrCtor = function () {
let o = Object.assign(instanceFunc, OcrCtor.prototype);
Object.defineProperties(instanceFunc, Object.getOwnPropertyDescriptors(OcrCtor.prototype));
return o;
};
OcrCtor.prototype = {
constructor: OcrCtor,
_modeName: modeName,
_forcibleModeArgIndex: 10,
mlkit: require('ocr-mlkit')(scriptRuntime, scope),
paddle: require('ocr-paddle')(scriptRuntime, scope),
get mode() {
return _mode;
},
set mode(mode) {
this.tap(mode);
},
tap(mode) {
if (mode === this.mlkit || String(mode).toLowerCase() === modeName.mlkit) {
_mode = modeName.mlkit;
} else if (mode === this.paddle || String(mode).toLowerCase() === modeName.paddle) {
_mode = modeName.paddle;
} else {
_mode = modeName.unknown;
throw TypeError(`Unknown mode (value: ${mode}, species: ${species(mode)}) for ocr.tap(mode)`);
}
},
recognizeText() {
if (typeof arguments[0] === 'string') {
// @Signature
// recognizeText(imgPath: string, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
// recognizeText(imgPath: string, region: Images.Options.Region): string[];
let img = images.read(/* path = */ arguments[0]);
if (img === null) {
throw TypeError(`Invalid image of path "${arguments[0]}" for ocr.recognizeText(img, options?)`);
}
// @Overload
// recognizeText(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
// recognizeText(img: ImageWrapper, region: Images.Options.Region): string[];
return this.recognizeText(img.oneShot(), arguments[1]);
}
if (_.shouldTakenAsRegion(arguments[1])) {
// @Signature recognizeText(img: ImageWrapper, region: Images.Options.Region): string[];
// @Overload recognizeText(img: ImageWrapper, options: DetectOptionsMLKit | DetectOptionsPaddle): string[];
return this.recognizeText(img, { region: arguments[1] });
}
// @Signature recognizeText(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): string[];
/** @type {Internal.Ocr.DetectOptions} */
let opt = /* options */ arguments[1] || {};
let region = opt.region;
if (region === null) {
return [];
}
/** @type Internal.Ocr.RecognizeTextMethod */
let recognizeTextMethod;
switch (arguments[OcrCtor.prototype._forcibleModeArgIndex] || _mode) {
case modeName.mlkit:
recognizeTextMethod = this.mlkit.recognizeTextMethodCreator(opt);
break;
case modeName.paddle:
recognizeTextMethod = this.paddle.recognizeTextMethodCreator(opt);
break;
default:
throw TypeError(`Can't call ocr.recognizeText with an unknown mode (value: ${_mode}, species: ${species(_mode)})`);
}
let img = arguments[0];
if (region === undefined) {
return recognizeTextMethod(img);
}
let results = recognizeTextMethod(
images.clip(img, region).oneShot(),
);
img.shoot();
return results;
},
detect() {
if (typeof arguments[0] === 'string') {
// @Signature
// detect(imgPath: string, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
// detect(imgPath: string, region: Images.Options.Region): org.autojs.autojs.runtime.api.OcrResult[];
let img = images.read(/* path = */ arguments[0]);
if (img === null) {
throw TypeError(`Invalid image of path "${arguments[0]}" for ocr.detect(img, options?)`);
}
// @Overload
// detect(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
// detect(img: ImageWrapper, region: Images.Options.Region): org.autojs.autojs.runtime.api.OcrResult[];
return this.detect(img.oneShot(), arguments[1]);
}
if (_.shouldTakenAsRegion(arguments[1])) {
// @Signature detect(img: ImageWrapper, region: Images.Options.Region): org.autojs.autojs.runtime.api.OcrResult[];
// @Overload detect(img: ImageWrapper, options: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
return this.detect(img, { region: arguments[1] });
}
// @Signature detect(img: ImageWrapper, options?: DetectOptionsMLKit | DetectOptionsPaddle): org.autojs.autojs.runtime.api.OcrResult[];
let opt = /* options */ arguments[1] || {};
let region = opt.region;
if (region === null) {
return [];
}
/** type {Internal.Ocr.DetectMethod} */
let detectMethod;
switch (_mode) {
case modeName.mlkit:
detectMethod = this.mlkit.detectMethodCreator(opt);
break;
case modeName.paddle:
detectMethod = this.paddle.detectMethodCreator(opt);
break;
default:
throw TypeError(`Can't call ocr.detect with an unknown mode (value: ${_mode}, species: ${species(_mode)})`);
}
let img = arguments[0];
if (region === undefined) {
return detectMethod(img);
}
let results = detectMethod(images.clip(img, region).oneShot());
results.forEach((result) => {
let rect = images.buildRegion(img, region);
result.bounds.offset(rect.x, rect.y);
});
img.shoot();
return results;
},
summary() {
return [
`[ OCR summary ]`,
`Current mode: ${this.mode}`,
`Available modes: [ ${Object.values(modeName).filter(n => n !== modeName.unknown).join(', ')} ]`,
].join('\n');
},
toString() {
return this.summary();
},
};
/* Set prototype descriptors. */
Object.defineProperties(OcrCtor.prototype, {
_modeName: defaultPrivateDescriptor,
_forcibleModeArgIndex: defaultPrivateDescriptor,
mode: { configurable: false },
constructor: defaultProtectedDescriptor,
mlkit: defaultProtectedDescriptor,
paddle: defaultProtectedDescriptor,
tap: defaultProtectedDescriptor,
summary: defaultProtectedDescriptor,
toString: defaultProtectedDescriptor,
});
return OcrCtor;
})(),
shouldTakenAsRegion(o) {
return o instanceof org.opencv.core.Rect
|| o instanceof android.graphics.Rect
|| Array.isArray(o);
},
};
/**
* @type {Internal.Ocr}
*/
const ocr = new _.OcrCtor();
/* Init OCR mode with MLKit. */
ocr.mode = 'mlkit';
return ocr;
};