6.5.0 - 新增 opencc 模块; 修复编辑器问题; 优化打包应用功能及文件管理器

This commit is contained in:
SuperMonster003
2023-12-02 13:52:14 +08:00
parent afc0bce2c9
commit 17616504ab
907 changed files with 6766 additions and 3005 deletions

View File

@@ -0,0 +1,26 @@
/**
* @author TonyJiangWJ
*/
!function internalApiForPaddleOcr() {
console.show();
// 指定是否用精简版模型, 速度较快, 默认为 true
let useSlim = false;
// CPU 线程数量, 实际好像没啥作用
let cpuThreadNum = 4;
let start = new Date();
let img = images.read('test.png');
let results = ocr.paddle.detect(img, { useSlim, cpuThreadNum });
toastLog(`识别结束, 耗时: ${new Date() - start}ms`);
log(`识别结果: ${JSON.stringify(
Array.from(results).map((result) => {
return { label: result.label, confidence: result.confidence, bounds: result.bounds };
}))}`);
// 回收图片
img.recycle();
}();

View File

@@ -0,0 +1,54 @@
/**
* @author TonyJiangWJ
*/
!function originalClassesForPaddleOcr() {
const Predictor = com.baidu.paddle.lite.ocr.Predictor;
console.show();
// 指定是否用精简版模型 速度较快
let useSlim = false;
// 创建检测器
let predictor = new Predictor();
// predictor.cpuThreadNum = 4 //可以自定义使用CPU的线程数
// predictor.checkModelLoaded = false // 可以自定义是否需要校验模型是否成功加载 默认开启 使用内置Base64图片进行校验 识别测试文本来校验模型是否加载成功
// 初始化模型 首次运行时会比较耗时
let loading = threads.disposable();
// 建议在新线程中初始化模型
threads.start(function () {
loading.setAndNotify(predictor.init(context, useSlim));
// loading.setAndNotify(predictor.init(context)) 为默认不使用精简版
// 内置默认 modelPath 为 models/ocr_v3_for_cpu初始化自定义模型请写绝对路径否则无法获取到
// 内置默认 labelPath 为 labels/ppocr_keys_v1.txt
// let modelPath = files.path('./models/customize') // 指定自定义模型路径
// let labelPath = files.path('./models/customize') // 指定自定义label路径
// 使用自定义模型时det rec cls三个模型文件名称需要手动指定
// predictor.detModelFilename = 'det_opt.nb'
// predictor.recModelFilename = 'rec_opt.nb'
// predictor.clsModelFilename = 'cls_opt.nb'
// loading.setAndNotify(predictor.init(context, modelPath, labelPath))
});
let loadSuccess = loading.blockedGet();
toastLog(`加载模型结果:${loadSuccess}`);
let start = new Date();
let img = images.read('test.png');
let results = predictor.runOcr(img.getBitmap());
toastLog(`识别结束, 耗时:${new Date() - start}ms`);
log(`识别结果: ${JSON.stringify(results.toArray().map((result) => {
return { label: result.label, confidence: result.confidence, bounds: result.bounds };
}))}`);
// 释放模型 用于释放native内存 非必需
// predictor.releaseModel()
// 回收图片
img.recycle();
}();

View File

@@ -0,0 +1,198 @@
/**
* create by TonyJiangWJ
*/
!function sampleForPaddleOcr() {
const Predictor = com.baidu.paddle.lite.ocr.Predictor;
let currentEngine = engines.myEngine();
let runningEngines = engines.all();
let currentSource = `${currentEngine.getSource()}`;
if (runningEngines.length > 1) {
runningEngines.forEach(compareEngine => {
let compareSource = `${compareEngine.getSource()}`;
if (currentEngine.getId() !== compareEngine.getId() && compareSource === currentSource) {
// 强制关闭同名的脚本
compareEngine.forceStop();
}
});
}
if (!requestScreenCapture()) {
toastLog('请求截图权限失败');
exit();
}
sleep(1000);
// 指定是否用精简版模型 速度较快
let useSlim = true;
// 创建检测器
let predictor = new Predictor();
// predictor.cpuThreadNum = 4 // 可以自定义使用CPU的线程数
// predictor.checkModelLoaded = false // 可以自定义是否需要校验模型是否成功加载 默认开启 使用内置Base64图片进行校验 识别测试文本来校验模型是否加载成功
// 初始化模型 首次运行时会比较耗时
let loading = threads.disposable();
// 建议在新线程中初始化模型
threads.start(function () {
loading.setAndNotify(predictor.init(context, useSlim));
// loading.setAndNotify(predictor.init(context)) 为默认不使用精简版
// 内置默认 modelPath 为 models/ocr_v3_for_cpu初始化自定义模型请写绝对路径否则无法获取到
// 内置默认 labelPath 为 labels/ppocr_keys_v1.txt
// let modelPath = files.path('./models/customize') // 指定自定义模型路径
// let labelPath = files.path('./models/customize') // 指定自定义label路径
// 使用自定义模型时det rec cls三个模型文件名称需要手动指定
// predictor.detModelFilename = 'det_opt.nb'
// predictor.recModelFilename = 'rec_opt.nb'
// predictor.clsModelFilename = 'cls_opt.nb'
// loading.setAndNotify(predictor.init(context, modelPath, labelPath))
});
let loadSuccess = loading.blockedGet();
if (!loadSuccess) {
toastLog('初始化ocr失败');
exit();
}
// 识别结果和截图信息
let result = [];
let img = null;
let running = true;
let capturing = true;
/**
* 截图并识别OCR文本信息
*/
function captureAndOcr() {
capturing = true;
img && img.recycle();
img = captureScreen();
if (!img) {
toastLog('截图失败');
}
let start = new Date();
result = predictor.runOcr(img.getBitmap());
toastLog(`耗时${new Date() - start}ms`);
capturing = false;
}
captureAndOcr();
// 获取状态栏高度
let offset = -getStatusBarHeightCompat();
// 绘制识别结果
let window = floaty.rawWindow(
<canvas id="canvas" layout_weight="1"/>,
);
// 设置悬浮窗位置
ui.post(() => {
window.setPosition(0, offset);
window.setSize(device.width, device.height);
window.setTouchable(false);
});
// 操作按钮
let clickButtonWindow = floaty.rawWindow(
<vertical>
<button id="captureAndOcr" text="截图识别"/>
<button id="closeBtn" text="退出"/>
</vertical>,
);
ui.run(function () {
clickButtonWindow.setPosition(device.width / 2 - ~~(clickButtonWindow.getWidth() / 2), device.height * 0.65);
});
// 点击识别
clickButtonWindow['captureAndOcr'].click(function () {
result = [];
ui.run(function () {
clickButtonWindow.setPosition(device.width, device.height);
});
setTimeout(() => {
captureAndOcr();
ui.run(function () {
clickButtonWindow.setPosition(device.width / 2 - ~~(clickButtonWindow.getWidth() / 2), device.height * 0.65);
});
}, 500);
});
// 点击关闭
clickButtonWindow['closeBtn'].click(function () {
exit();
});
let Typeface = android.graphics.Typeface;
let paint = new Paint();
paint.setStrokeWidth(1);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setTextAlign(Paint.Align.LEFT);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setDither(true);
window.canvas.on('draw', function (canvas) {
if (!running || capturing) {
return;
}
// 清空内容
canvas.drawColor(0xFFFFFF, android.graphics.PorterDuff.Mode.CLEAR);
if (result && result.length > 0) {
for (let i = 0; i < result.length; i++) {
let ocrResult = result[i];
drawRectAndText(ocrResult.label, ocrResult.bounds, '#00ff00', canvas, paint);
}
}
});
setInterval(() => {
/* Empty body. */
}, 10000);
events.on('exit', () => {
// 标记停止 避免canvas导致闪退
running = false;
// 撤销监听
window.canvas.removeAllListeners();
// 回收图片
img && img.recycle();
});
/**
* 绘制文本和方框
*/
function drawRectAndText(desc, rect, colorStr, canvas, paint) {
let color = colors.parseColor(colorStr);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
// 反色
paint.setARGB(255, 255 - (color >> 16 & 0xff), 255 - (color >> 8 & 0xff), 255 - (color & 0xff));
canvas.drawRect(rect, paint);
paint.setARGB(255, color >> 16 & 0xff, color >> 8 & 0xff, color & 0xff);
paint.setStrokeWidth(1);
paint.setTextSize(20);
paint.setStyle(Paint.Style.FILL);
canvas.drawText(desc, rect.left, rect.top, paint);
paint.setTextSize(10);
paint.setStrokeWidth(1);
paint.setARGB(255, 0, 0, 0);
}
/**
* 获取状态栏高度
*/
function getStatusBarHeightCompat() {
let result = 0;
let resId = context.getResources().getIdentifier('status_bar_height', 'dimen', 'android');
if (resId > 0) {
result = context.getResources().getDimensionPixelOffset(resId);
}
if (result <= 0) {
result = context.getResources().getDimensionPixelOffset(R.dimen.dimen_25dp);
}
return result;
}
}();

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB