p7zip支持以及添加OCR、p7zip的API及示例文件

This commit is contained in:
Aioure 2022-02-08 12:30:54 +08:00 committed by TonyJiangWJ
parent 375ad67239
commit c4e7a1a810
21 changed files with 418 additions and 5 deletions

View File

@ -0,0 +1,36 @@
//目录路径(必须是完整路径)
var dirPath = "/sdcard/脚本/";
if(!files.isDir(dirPath)) files.create(dirPath);
//压缩文件路径(必须是完整路径)
var filePath = "/sdcard/脚本.7z";
//压缩类型
//支持的压缩类型包括:zip 7z bz2 bzip2 tbz2 tbz gz gzip tgz tar wim swm xz txz。
var type = "7z";
//压缩密码
var password = "password"
//7z加密压缩(若文件已存在则跳过)
//zips.A(type, filePath, dirPath, password)
//压缩
switch (zips.A(type, filePath, dirPath)) {
case 0:
toastLog("压缩成功!文件已保存为: " + filePath)
break;
case 1:
toastLog("压缩结束,存在非致命错误(例如某些文件正在被使用,没有被压缩)")
break;
case 2:
toastLog("致命错误")
break;
case 7:
toastLog("命令行错误")
break;
case 8:
toastLog("没有足够内存")
break;
case 255:
toastLog("用户中止操作")
break;
default: toastLog("未知错误")
}

Binary file not shown.

View File

@ -0,0 +1,33 @@
//压缩文件路径(必须是完整路径)
var filePath = files.path("./bonus.rar");
//目录路径(必须是完整路径)
var dirPath = "/sdcard/脚本";
//压缩密码
var password = "password"
//支持的解压缩类型包括zip、7z、bz2、bzip2、tbz2、tbz、gz、gzip、tgz、tar、wim、swm、xz、txz以及rar、chm、iso、msi等众多格式。
//解压无加密的压缩包(若文件已存在则跳过)
//zips.X(filePath, dirPath)
//解压加密的压缩包(若文件已存在则跳过)
switch (zips.X(filePath, dirPath, password)) {
case 0:
toastLog("解压缩成功!请到 " + dirPath + " 目录下查看。")
break;
case 1:
toastLog("压缩结束,存在非致命错误(例如某些文件正在被使用,没有被压缩)")
break;
case 2:
toastLog("致命错误")
break;
case 7:
toastLog("命令行错误")
break;
case 8:
toastLog("没有足够内存")
break;
case 255:
toastLog("用户中止操作")
break;
default: toastLog("未知错误")
}

View File

@ -0,0 +1,19 @@
const img = images.read("./test.png");
const cpuThreadNum = 4;
// PaddleOCR 移动端提供了两种模型ocr_v2_for_cpu与ocr_v2_for_cpu(slim),此选项用于选择加载的模型,默认true使用v2的slim版(速度更快)false使用v2的普通版(准确率更高)
var useSlim = true;
// 识别图片中的文字返回完整识别信息兼容百度OCR格式
const result = ocr.R(img, cpuThreadNum, useSlim);
// 可以使用简化的调用命令默认参数cpuThreadNum = 4, useSlim = true;
// const result = ocr.R(img);
toastLog("完整识别信息兼容百度OCR格式: " + JSON.stringify(result));
// 识别图片中的文字,只返回文本识别信息(字符串列表)。
const stringList = ocr.T(img, cpuThreadNum, useSlim);
// 可以使用简化的调用命令默认参数cpuThreadNum = 4, useSlim = true;
// const stringList = ocr.T(img);
toastLog("文本识别信息(字符串列表): " + JSON.stringify(stringList));
// 释放模型 用于释放native内存
ocr.release()
// 回收图片
img.recycle()

View File

@ -0,0 +1,2 @@
configurations.maybeCreate("default")
artifacts.add("default", file('libp7zip-1.7.2.aar'))

Binary file not shown.

View File

@ -57,7 +57,8 @@ public class OCRPredictorNative {
}
public void destory(){
// 原代码中该方法名为destory()此处应该是拼写错误其它类中调用此方法的名称也已修正
public void destroy(){
if (nativePointer != 0) {
release(nativePointer);
nativePointer = 0;
@ -105,6 +106,6 @@ public class OCRPredictorNative {
@Override
protected void finalize() throws Throwable {
super.finalize();
destory();
destroy();
}
}

View File

@ -2,11 +2,16 @@ package com.baidu.paddle.lite.ocr;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Parcelable;
public class OcrResult {
public float confidence;
public float preprocessTime;
public float inferenceTime;
public String words;
public Rect bounds;
public RectLocation location;
private String label;
private float confidence;
private Rect bounds;
public OcrResult() {
}
@ -61,4 +66,18 @@ public class OcrResult {
public void setBounds(Rect bounds) {
this.bounds = bounds;
}
public static class RectLocation {
public int left;
public int top;
public int width;
public int height;
public RectLocation(int left, int top, int width, int height) {
this.left = left;
this.top = top;
this.width = width;
this.height = height;
}
}
}

View File

@ -7,6 +7,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;
import java.io.File;
@ -42,6 +43,7 @@ public class Predictor {
protected volatile String outputResult = "";
protected float preprocessTime = 0;
protected float postprocessTime = 0;
protected boolean useSlim = true;;
public Predictor() {
@ -140,7 +142,7 @@ public class Predictor {
public void releaseModel() {
if (paddlePredictor != null) {
paddlePredictor.destory();
paddlePredictor.destroy();
paddlePredictor = null;
}
isLoaded = false;
@ -434,4 +436,126 @@ public class Predictor {
}
}
public boolean init(Context appCtx, boolean useSlim) {
if (!this.isLoaded || (this.useSlim != useSlim)) {
loadLabel(appCtx, "labels/ppocr_keys_v1.txt");
if (useSlim) {
loadModel(appCtx, "models/ocr_v2_for_cpu(slim)", 4, "LITE_POWER_HIGH");
} else {
loadModel(appCtx, "models/ocr_v2_for_cpu", 4, "LITE_POWER_HIGH");
}
}
this.isLoaded = true;
this.useSlim = useSlim;
Log.i(TAG, "isLoaded: " + this.isLoaded);
return this.isLoaded;
}
public List<OcrResult> transformData(List<OcrResultModel> OcrResultModelList) {
if (OcrResultModelList == null) {
return Collections.emptyList();
}
List<OcrResult> words_result = new ArrayList<>();
for (OcrResultModel model : OcrResultModelList) {
List<Point> pointList = model.getPoints();
if (pointList.isEmpty()) {
continue;
}
Point firstPoint = pointList.get(0);
int left = firstPoint.x;
int top = firstPoint.y;
int right = firstPoint.x;
int bottom = firstPoint.y;
for (Point p : pointList) {
if (p.x < left) {
left = p.x;
}
if (p.x > right) {
right = p.x;
}
if (p.y < top) {
top = p.y;
}
if (p.y > bottom) {
bottom = p.y;
}
}
OcrResult ocrResult = new OcrResult();
ocrResult.preprocessTime = preprocessTime;
ocrResult.inferenceTime = inferenceTime;
ocrResult.confidence = model.getConfidence();
ocrResult.words = model.getLabel().trim().replace("\r", "");
ocrResult.location = new OcrResult.RectLocation(left, top, Math.abs(right - left), Math.abs(bottom - top));
ocrResult.bounds = new Rect(left, top, right, bottom);
words_result.add(ocrResult);
}
return words_result;
}
public List<OcrResult> ocr(Bitmap inputImage, int cpuThreadNum) {
this.cpuThreadNum = cpuThreadNum;
if (inputImage == null) {
return Collections.emptyList();
}
// Pre-process image, and feed input tensor with pre-processed data
Bitmap scaleImage = Utils.resizeWithStep(inputImage, Long.valueOf(inputShape[2]).intValue(), 32);
Date start = new Date();
int channels = (int) inputShape[1];
int width = scaleImage.getWidth();
int height = scaleImage.getHeight();
float[] inputData = new float[channels * width * height];
if (channels == 3) {
int[] channelIdx = null;
if (inputColorFormat.equalsIgnoreCase("RGB")) {
channelIdx = new int[]{0, 1, 2};
} else if (inputColorFormat.equalsIgnoreCase("BGR")) {
channelIdx = new int[]{2, 1, 0};
} else {
Log.i(TAG, "Unknown color format " + inputColorFormat + ", only RGB and BGR color format is " +
"supported!");
return Collections.emptyList();
}
int[] channelStride = new int[]{width * height, width * height * 2};
int[] pixels = new int[width * height];
scaleImage.getPixels(pixels, 0, scaleImage.getWidth(), 0, 0, scaleImage.getWidth(), scaleImage.getHeight());
for (int i = 0; i < pixels.length; i++) {
int color = pixels[i];
float[] rgb = new float[]{(float) red(color) / 255.0f, (float) green(color) / 255.0f,
(float) blue(color) / 255.0f};
inputData[i] = (rgb[channelIdx[0]] - inputMean[0]) / inputStd[0];
inputData[i + channelStride[0]] = (rgb[channelIdx[1]] - inputMean[1]) / inputStd[1];
inputData[i + channelStride[1]] = (rgb[channelIdx[2]] - inputMean[2]) / inputStd[2];
}
} else if (channels == 1) {
int[] pixels = new int[width * height];
scaleImage.getPixels(pixels, 0, scaleImage.getWidth(), 0, 0, scaleImage.getWidth(), scaleImage.getHeight());
for (int i = 0; i < pixels.length; i++) {
int color = pixels[i];
float gray = (float) (red(color) + green(color) + blue(color)) / 3.0f / 255.0f;
inputData[i] = (gray - inputMean[0]) / inputStd[0];
}
} else {
Log.i(TAG, "Unsupported channel size " + Integer.toString(channels) + ", only channel 1 and 3 is " +
"supported!");
return Collections.emptyList();
}
float[] pixels = inputData;
Log.i(TAG, "pixels " + pixels[0] + " " + pixels[1] + " " + pixels[2] + " " + pixels[3]
+ " " + pixels[pixels.length / 2] + " " + pixels[pixels.length / 2 + 1] + " " + pixels[pixels.length - 2] + " " + pixels[pixels.length - 1]);
Date end = new Date();
preprocessTime = (float) (end.getTime() - start.getTime());
// Warm up
for (int i = 0; i < warmupIterNum; i++) {
paddlePredictor.runImage(inputData, width, height, channels, inputImage);
}
warmupIterNum = 0; // do not need warm
// Run inference
start = new Date();
ArrayList<OcrResultModel> results = paddlePredictor.runImage(inputData, width, height, channels, inputImage);
end = new Date();
inferenceTime = (float) (end.getTime() - start.getTime());
results = postprocess(results);
return transformData(results);
}
}

View File

@ -75,6 +75,7 @@ dependencies {
api project(path: ':autojs-aar:term')
api project(path: ':autojs-aar:rhino-jdk7')
api project(path: ':autojs-aar:paddleocr')
api project(path: ':autojs-aar:p7zip')
api project(path: ':common')
api project(path: ':automator')
implementation 'com.rmtheis:tess-two:9.1.0'

View File

@ -141,5 +141,7 @@ module.exports = function(runtime, global){
return buildTypes.release;
}
global.zips = Object.create(runtime.zips);
global.ocr = Object.create(runtime.ocr);
}

View File

@ -32,8 +32,10 @@ import com.stardust.autojs.runtime.api.Files;
import com.stardust.autojs.runtime.api.Floaty;
import com.stardust.autojs.runtime.api.Images;
import com.stardust.autojs.runtime.api.Media;
import com.stardust.autojs.runtime.api.OCR;
import com.stardust.autojs.runtime.api.Plugins;
import com.stardust.autojs.runtime.api.Sensors;
import com.stardust.autojs.runtime.api.SevenZip;
import com.stardust.autojs.runtime.api.Threads;
import com.stardust.autojs.runtime.api.Timers;
import com.stardust.autojs.runtime.api.UI;
@ -193,6 +195,12 @@ public class ScriptRuntime {
@ScriptVariable
public final Plugins plugins;
@ScriptVariable
public SevenZip zips;
@ScriptVariable
public OCR ocr;
private Images images;
private static WeakReference<Context> applicationContext;
@ -224,6 +232,8 @@ public class ScriptRuntime {
files = new Files(this);
media = new Media(context, this);
plugins = new Plugins(context, this);
zips = new SevenZip();
ocr = new OCR();
}
public void init() {

View File

@ -0,0 +1,77 @@
package com.stardust.autojs.runtime.api;
import android.graphics.Bitmap;
import android.os.Looper;
import android.util.Log;
import com.baidu.paddle.lite.ocr.OcrResult;
import com.baidu.paddle.lite.ocr.Predictor;
import com.stardust.app.GlobalAppContext;
import com.stardust.autojs.core.image.ImageWrapper;
import java.util.Collections;
import java.util.List;
public class OCR {
private Predictor mPredictor = new Predictor();
public synchronized boolean init(boolean useSlim) {
if (!mPredictor.isLoaded) {
if (Looper.getMainLooper() == Looper.myLooper()) {
new Thread(() -> {
mPredictor.init(GlobalAppContext.get(), useSlim);
}).start();
} else {
mPredictor.init(GlobalAppContext.get(), useSlim);
}
}
return mPredictor.isLoaded;
}
public void release() {
mPredictor.releaseModel();
}
public List<OcrResult> R(ImageWrapper image, int cpuThreadNum, boolean useSlim) {
if (image == null) {
return Collections.emptyList();
}
Bitmap bitmap = image.getBitmap();
if (bitmap == null || bitmap.isRecycled()) {
return Collections.emptyList();
}
init(useSlim);
return mPredictor.ocr(bitmap, cpuThreadNum);
}
public List<OcrResult> R(ImageWrapper image, int cpuThreadNum) {
return R(image, cpuThreadNum, true);
}
public List<OcrResult> R(ImageWrapper image) {
return R(image, 4, true);
}
public String[] T(ImageWrapper image, int cpuThreadNum, boolean useSlim) {
List<OcrResult> words_result = R(image, cpuThreadNum, useSlim);
String[] outputResult = new String[words_result.size()];
for (int i = 0; i < words_result.size(); i++) {
outputResult[i] = words_result.get(i).words;
Log.i("outputResult", outputResult[i].toString()); // show LOG in Logcat panel
}
return outputResult;
}
public String[] T(ImageWrapper image, int cpuThreadNum) {
return T(image, cpuThreadNum, true);
}
public String[] T(ImageWrapper image) {
return T(image, 4, true);
}
}

View File

@ -0,0 +1,88 @@
package com.stardust.autojs.runtime.api;
import com.hzy.libp7zip.P7ZipApi;
import com.stardust.autojs.runtime.exception.ScriptException;
import com.stardust.pio.PFiles;
public class SevenZip {
public int cmdExec(String cmdStr) {
try {
return P7ZipApi.executeCommand(cmdStr);
} catch (Exception e) {
throw new ScriptException(e);
}
}
public int A(String type, String destFilePath, String srcPath) {
String typeOption = "";
if (!type.trim().isEmpty()) {
typeOption = " -t" + type.trim();
}
String cmdStr = "7z";
if (PFiles.isFile(srcPath)) {
cmdStr = "7z a -y" + typeOption + " -ms=off -mx=1 -mmt " + destFilePath + " " + srcPath;
} else if (PFiles.isDir(srcPath)) {
cmdStr = "7z a -y" + typeOption + " -ms=off -mx=1 -mmt -r " + destFilePath + " " + srcPath;
}
try {
return P7ZipApi.executeCommand(cmdStr);
} catch (Exception e) {
throw new ScriptException(e);
}
}
public int A(String type, String destFilePath, String srcPath, String password) {
String typeOption = "";
if (!type.trim().isEmpty()) {
typeOption = " -t" + type.trim();
}
String cmdStr = "7z";
if (PFiles.isFile(srcPath)) {
cmdStr = "7z a -y" + typeOption + " -ms=off -mx=1 -mmt -p" + password + " " + destFilePath + " " + srcPath;
} else if (PFiles.isDir(srcPath)) {
cmdStr = "7z a -y" + typeOption + " -ms=off -mx=1 -mmt -r -p" + password + " " + destFilePath + " " + srcPath;
}
try {
return P7ZipApi.executeCommand(cmdStr);
} catch (Exception e) {
throw new ScriptException(e);
}
}
public int X(String filePath0, String dirPath1) {
String cmdStr = "7z x -y -aos " + filePath0;
if (PFiles.isFile(filePath0)) {
if (PFiles.isDir(dirPath1)) {
cmdStr = "7z x -y -aos -o" + dirPath1 + " " + filePath0 + "";
} else {
cmdStr = "7z x -y -aos " + filePath0 + "";
}
}
try {
return P7ZipApi.executeCommand(cmdStr);
} catch (Exception e) {
throw new ScriptException(e);
}
}
public int X(String filePath0, String dirPath1, String password) {
String cmdStr = "7z x -y -aos " + filePath0 + "";
if (password == "") {
X(filePath0, dirPath1);
} else {
if (PFiles.isFile(filePath0)) {
if (PFiles.isDir(dirPath1)) {
cmdStr = "7z x -y -aos -p" + password + " -o" + dirPath1 + " " + filePath0;
} else {
cmdStr = "7z x -y -aos -p" + password + " " + filePath0;
}
}
}
try {
return P7ZipApi.executeCommand(cmdStr);
} catch (Exception e) {
throw new ScriptException(e);
}
}
}

View File

@ -11,3 +11,4 @@ include ':js-supports:autojs-tool-common'
include ':js-supports:kill-pro-limit'
include ':autojs-aar:rhino-jdk7'
include ':autojs-aar:paddleocr'
include ':autojs-aar:p7zip'