新增 images.inRange(), images.findCircles, images.matToImage

修复 调用模块时模块本身的错误提醒不明显的问题
This commit is contained in:
hyb1996
2018-10-30 16:28:17 +08:00
parent 2acf9123c9
commit c92d869fa1
8 changed files with 432 additions and 370 deletions

View File

@@ -1,6 +1,7 @@
package org.autojs.autojs; package org.autojs.autojs;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.usage.UsageStatsManager;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;

View File

@@ -1,11 +1,28 @@
module.exports = function (__runtime__, scope) { module.exports = function (runtime, scope) {
function images(){
}
util.__assignFunctions__(runtime.images, images, ['requestScreenCapture', 'captureScreen', 'read', 'copy', 'load', 'clip', 'pixel'])
images.opencvImporter = JavaImporter(
org.opencv.core.Point,
org.opencv.core.Point3,
org.opencv.core.Rect,
org.opencv.core.Algorithm,
org.opencv.core.Scalar,
org.opencv.core.Size,
org.opencv.core.Core,
org.opencv.core.CvException,
org.opencv.core.CvType,
org.opencv.core.TermCriteria,
org.opencv.core.RotatedRect,
org.opencv.core.Range,
org.opencv.imgproc.Imgproc,
com.stardust.autojs.core.opencv
);
with (images.opencvImporter) {
const defaultColorThreshold = 4; const defaultColorThreshold = 4;
importPackage(org.opencv.core);
const Imgproc = org.opencv.imgproc.Imgproc;
var images = {}; var colors = Object.create(runtime.colors);
var colors = Object.create(__runtime__.colors);
colors.alpha = function (color) { colors.alpha = function (color) {
color = parseColor(color); color = parseColor(color);
return color >>> 24; return color >>> 24;
@@ -32,58 +49,65 @@ module.exports = function (__runtime__, scope) {
return colorDetector.detectsColor(colors.red(c2), colors.green(c2), colors.blue(c2)); return colorDetector.detectsColor(colors.red(c2), colors.green(c2), colors.blue(c2));
} }
if (android.os.Build.VERSION.SDK_INT < 19) { var javaImages = runtime.getImages();
return images;
}
var rtImages = __runtime__.getImages(); var colorFinder = javaImages.colorFinder;
var colorFinder = rtImages.colorFinder;
images.requestScreenCapture = rtImages.requestScreenCapture.bind(rtImages);
images.captureScreen = rtImages.captureScreen.bind(rtImages);
images.read = rtImages.read.bind(rtImages);
images.copy = rtImages.copy.bind(rtImages);
images.load = rtImages.load.bind(rtImages);
images.clip = rtImages.clip.bind(rtImages);
images.save = function (img, path, format, quality) { images.save = function (img, path, format, quality) {
format = format || "png"; format = format || "png";
quality = quality == undefined ? 100 : quality; quality = quality == undefined ? 100 : quality;
return rtImages.save(img, path, format, quality); return javaImages.save(img, path, format, quality);
} }
images.saveImage = images.save; images.saveImage = images.save;
images.pixel = rtImages.pixel;
images.grayscale = function (img, dstCn) { images.grayscale = function (img, dstCn) {
return images.cvtColor(img, "BGR2GRAY", dstCn); return images.cvtColor(img, "BGR2GRAY", dstCn);
} }
images.threshold = function (img, threshold, maxVal, type) { images.threshold = function (img, threshold, maxVal, type) {
var mat = newMat(); var mat = new Mat();
type = type || "BINARY"; type = type || "BINARY";
type = Imgproc["THRESH_" + type]; type = Imgproc["THRESH_" + type];
Imgproc.threshold(img.mat, mat, threshold, maxVal, type); Imgproc.threshold(img.mat, mat, threshold, maxVal, type);
return matToImage(mat); return images.matToImage(mat);
} }
images.inRange = function (img, lowerBound, upperBound) {
var lb, ub;
if (typeof (lowerBound) == 'string') {
if (typeof (upperBound) == 'string') {
lb = new Scalar(colors.red(lowerBound), colors.green(lowerBound),
colors.blue(lowerBound), colors.alpha(lowerBound));
ub = new Scalar(colors.red(upperBound), colors.green(upperBound),
colors.blue(upperBound), colors.alpha(lowerBound));
} else if (typeof (upperBound) == 'number') {
var color = lowerBound;
var threshold = upperBound;
lb = new Scalar(colors.red(color) - threshold, colors.green(color) - threshold,
colors.blue(color) - threshold, colors.alpha(color));
ub = new Scalar(colors.red(color) + threshold, colors.green(color) + threshold,
colors.blue(color) + threshold, colors.alpha(color));
}else{
throw new TypeError('lowerBound = ' + lowerBound, + 'upperBound = ' + upperBound);
}
}
var bi = new Mat();
Core.inRange(img.mat, lb, ub, bi);
return images.matToImage(bi);
}
images.adaptiveThreshold = function(img, maxValue, adaptiveMethod, thresholdType, blockSize, C){ images.adaptiveThreshold = function(img, maxValue, adaptiveMethod, thresholdType, blockSize, C){
var mat = newMat(); var mat = new Mat();
adaptiveMethod = Imgproc["ADAPTIVE_THRESH_" + adaptiveMethod]; adaptiveMethod = Imgproc["ADAPTIVE_THRESH_" + adaptiveMethod];
thresholdType = Imgproc["THRESH_" + thresholdType]; thresholdType = Imgproc["THRESH_" + thresholdType];
Imgproc.adaptiveThreshold(img.mat, mat, maxValue, adaptiveMethod, thresholdType, blockSize, C); Imgproc.adaptiveThreshold(img.mat, mat, maxValue, adaptiveMethod, thresholdType, blockSize, C);
return matToImage(mat); return images.matToImage(mat);
} }
images.blur = function (img, size, point, type) { images.blur = function (img, size, point, type) {
var mat = newMat(); var mat = new Mat();
size = newSize(size); size = newSize(size);
type = Imgproc["BORDER_" + (type || "CONSTANT")]; type = Imgproc["BORDER_" + (type || "CONSTANT")];
if (point == undefined) { if (point == undefined) {
@@ -91,49 +115,78 @@ module.exports = function (__runtime__, scope) {
} else { } else {
Imgproc.blur(img.mat, mat, size, new Point(point[0], point[1]), type); Imgproc.blur(img.mat, mat, size, new Point(point[0], point[1]), type);
} }
return matToImage(mat); return images.matToImage(mat);
} }
images.medianBlur = function (img, size) { images.medianBlur = function (img, size) {
var mat = newMat(); var mat = new Mat();
Imgproc.medianBlur(img.mat, mat, size); Imgproc.medianBlur(img.mat, mat, size);
return matToImage(mat); return images.matToImage(mat);
} }
images.gaussianBlur = function (img, size, sigmaX, sigmaY, type) { images.gaussianBlur = function (img, size, sigmaX, sigmaY, type) {
var mat = newMat(); var mat = new Mat();
size = newSize(size); size = newSize(size);
sigmaX = sigmaX == undefined ? 0 : sigmaX; sigmaX = sigmaX == undefined ? 0 : sigmaX;
sigmaY = sigmaY == undefined ? 0 : sigmaY; sigmaY = sigmaY == undefined ? 0 : sigmaY;
type = Imgproc["BORDER_" + (type || "DEFAULT")]; type = Imgproc["BORDER_" + (type || "DEFAULT")];
Imgproc.GaussianBlur(img.mat, mat, size, sigmaX, sigmaY, type); Imgproc.GaussianBlur(img.mat, mat, size, sigmaX, sigmaY, type);
return matToImage(mat); return images.matToImage(mat);
} }
images.cvtColor = function (img, code, dstCn) { images.cvtColor = function (img, code, dstCn) {
var mat = newMat(); var mat = new Mat();
code = Imgproc["COLOR_" + code]; code = Imgproc["COLOR_" + code];
if (dstCn == undefined) { if (dstCn == undefined) {
Imgproc.cvtColor(img.mat, mat, code); Imgproc.cvtColor(img.mat, mat, code);
} else { } else {
Imgproc.cvtColor(img.mat, mat, code, dstCn); Imgproc.cvtColor(img.mat, mat, code, dstCn);
} }
return matToImage(mat); return images.matToImage(mat);
}
images.findCircles = function(grayImg, options) {
options = options || {};
var mat = options.region == undefined ? grayImg.mat : new Mat(grayImg.mat, buildRegion(options.region, grayImg));
var resultMat = new Mat()
var dp = options.dp == undefined ? 1 : options.dp;
var minDst = options.minDst == undefined ? grayImg.height / 8 : options.minDst;
var param1 = options.param1 == undefined ? 100 : options.param1;
var param2 = options.param2 == undefined ? 100 : options.param2;
var minRadius = options.minRadius == undefined ? 0 : options.minRadius;
var maxRadius = options.maxRadius == undefined ? 0 : options.maxRadius;
Imgproc.HoughCircles(mat, resultMat, Imgproc.CV_HOUGH_GRADIENT, dp, minDst, param1, param2, minRadius, maxRadius);
var result = [];
for (var i = 0; i < resultMat.rows(); i++) {
for (var j = 0; j < resultMat.cols(); j++) {
var d = resultMat.get(i, j);
result.push({
x: d[0],
y: d[1],
radius: d[2]
});
}
}
if(options.region != undefined){
mat.release();
}
resultMat.release();
return result;
} }
images.resize = function(img, size, interpolation) { images.resize = function(img, size, interpolation) {
var mat = newMat(); var mat = new Mat();
interpolation = Imgproc["INTER_" + (interpolation || "LINEAR")]; interpolation = Imgproc["INTER_" + (interpolation || "LINEAR")];
Imgproc.resize(img.mat, mat, newSize(size), 0, 0, interpolation); Imgproc.resize(img.mat, mat, newSize(size), 0, 0, interpolation);
return matToImage(mat); return images.matToImage(mat);
} }
images.scale = function(img, fx, fy, interpolation) { images.scale = function(img, fx, fy, interpolation) {
var mat = newMat(); var mat = new Mat();
interpolation = Imgproc["INTER_" + (interpolation || "LINEAR")]; interpolation = Imgproc["INTER_" + (interpolation || "LINEAR")];
Imgproc.resize(img.mat, mat, newSize([0, 0]), fx, fy, interpolation); Imgproc.resize(img.mat, mat, newSize([0, 0]), fx, fy, interpolation);
return matToImage(mat); return images.matToImage(mat);
} }
images.detectsColor = function (img, color, x, y, threshold, algorithm) { images.detectsColor = function (img, color, x, y, threshold, algorithm) {
@@ -214,9 +267,9 @@ module.exports = function (__runtime__, scope) {
} }
var weakThreshold = options.weakThreshold || 0.7; var weakThreshold = options.weakThreshold || 0.7;
if (options.region) { if (options.region) {
return rtImages.findImage(img, template, weakThreshold, threshold, buildRegion(options.region, img), maxLevel); return javaImages.findImage(img, template, weakThreshold, threshold, buildRegion(options.region, img), maxLevel);
} else { } else {
return rtImages.findImage(img, template, weakThreshold, threshold, null, maxLevel); return javaImages.findImage(img, template, weakThreshold, threshold, null, maxLevel);
} }
} }
@@ -228,23 +281,23 @@ module.exports = function (__runtime__, scope) {
} }
images.fromBase64 = function (base64) { images.fromBase64 = function (base64) {
return rtImages.fromBase64(base64); return javaImages.fromBase64(base64);
} }
images.toBase64 = function (img, format, quality) { images.toBase64 = function (img, format, quality) {
format = format || "png"; format = format || "png";
quality = quality == undefined ? 100 : quality; quality = quality == undefined ? 100 : quality;
return rtImages.toBase64(img, format, quality); return javaImages.toBase64(img, format, quality);
} }
images.fromBytes = function (bytes) { images.fromBytes = function (bytes) {
return rtImages.fromBytes(bytes); return javaImages.fromBytes(bytes);
} }
images.toBytes = function (img, format, quality) { images.toBytes = function (img, format, quality) {
format = format || "png"; format = format || "png";
quality = quality == undefined ? 100 : quality; quality = quality == undefined ? 100 : quality;
return rtImages.toBytes(img, format, quality); return javaImages.toBytes(img, format, quality);
} }
images.readPixels = function (path) { images.readPixels = function (path) {
@@ -262,6 +315,9 @@ module.exports = function (__runtime__, scope) {
}; };
} }
images.matToImage = function(img){
return Image.ofMat(img);
}
function getColorDetector(color, algorithm, threshold) { function getColorDetector(color, algorithm, threshold) {
switch (algorithm) { switch (algorithm) {
@@ -304,14 +360,6 @@ module.exports = function (__runtime__, scope) {
return color; return color;
} }
function newMat() {
return new com.stardust.autojs.core.opencv.Mat();
}
function matToImage(mat) {
return com.stardust.autojs.core.image.ImageWrapper.ofMat(mat);
}
function newSize(size) { function newSize(size) {
if (!Array.isArray(size)) { if (!Array.isArray(size)) {
size = [size, size]; size = [size, size];
@@ -327,4 +375,5 @@ module.exports = function (__runtime__, scope) {
scope.colors = colors; scope.colors = colors;
return images; return images;
}
} }

View File

@@ -19,7 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
var formatRegExp = /%[sdj%]/g;
exports.extend = (function () { exports.extend = (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
@@ -30,7 +29,16 @@ exports.extend = (function () {
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}; };
})(); })();
exports.java = require("__java_util__"); exports.java = require("__java_util__");
exports.__assignFunctions__ = function(src, target, functions) {
for(let f of functions){
target[f] = src[f].bind(src);
}
}
var formatRegExp = /%[sdj%]/g;
exports.format = function(f) { exports.format = function(f) {
if (!isString(f)) { if (!isString(f)) {
var objects = []; var objects = [];

View File

@@ -30,7 +30,7 @@ module = (typeof module === 'undefined') ? {} : module;
NativeRequire.require = require; NativeRequire.require = require;
} }
function Module (id, parent, core) { function Module(id, parent, core) {
this.id = id; this.id = id;
this.core = core; this.core = core;
this.parent = parent; this.parent = parent;
@@ -56,7 +56,8 @@ module = (typeof module === 'undefined') ? {} : module;
}.bind(this); }.bind(this);
} }
Module._load = function _load (file, parent, core, main) { Module._load = function _load(file, parent, core, main) {
return NativeRequire.require(file);
var module = new Module(file, parent, core); var module = new Module(file, parent, core);
var body = readFile(module.filename, module.core); var body = readFile(module.filename, module.core);
var dir = new File(module.filename).getParent(); var dir = new File(module.filename).getParent();
@@ -68,20 +69,20 @@ module = (typeof module === 'undefined') ? {} : module;
return module.exports; return module.exports;
}; };
Module.runMain = function runMain (main) { Module.runMain = function runMain(main) {
var file = Require.resolve(main); var file = Require.resolve(main);
Module._load(file, undefined, false, true); Module._load(file, undefined, false, true);
}; };
function Require (id, parent) { function Require(id, parent) {
var normalizePath = normalizeName(id); var normalizePath = normalizeName(id);
if(builtInModules.indexOf(normalizePath) >= 0 && !files.exists(normalizePath)){ if (builtInModules.indexOf(normalizePath) >= 0 && !files.exists(normalizePath)) {
return NativeRequire.require(normalizePath); return NativeRequire.require(normalizePath);
} }
if(id === "events"){ if (id === "events") {
return events; return events;
} }
if(id.startsWith("http://") || id.startsWith("https://")){ if (id.startsWith("http://") || id.startsWith("https://")) {
return NativeRequire.require(id); return NativeRequire.require(id);
} }
@@ -105,7 +106,6 @@ module = (typeof module === 'undefined') ? {} : module;
file = file.path; file = file.path;
core = true; core = true;
} }
try {
if (Require.cache[file]) { if (Require.cache[file]) {
return Require.cache[file]; return Require.cache[file];
} else if (file.endsWith('.js')) { } else if (file.endsWith('.js')) {
@@ -113,14 +113,6 @@ module = (typeof module === 'undefined') ? {} : module;
} else if (file.endsWith('.json')) { } else if (file.endsWith('.json')) {
return loadJSON(file); return loadJSON(file);
} }
} catch (ex) {
if (ex instanceof java.lang.Exception) {
throw new ModuleError('Cannot load module ' + id, 'LOAD_ERROR', ex);
} else {
System.out.println('Cannot load module ' + id + ' LOAD_ERROR');
throw ex;
}
}
} }
Require.resolve = function (id, parent) { Require.resolve = function (id, parent) {
@@ -142,13 +134,13 @@ module = (typeof module === 'undefined') ? {} : module;
Require.root = files.cwd();//System.getProperty('user.dir'); Require.root = files.cwd();//System.getProperty('user.dir');
Require.NODE_PATH = undefined; Require.NODE_PATH = undefined;
function findRoots (parent) { function findRoots(parent) {
var r = []; var r = [];
r.push(findRoot(parent)); r.push(findRoot(parent));
return r.concat(Require.paths()); return r.concat(Require.paths());
} }
function parsePaths (paths) { function parsePaths(paths) {
if (!paths) { if (!paths) {
return []; return [];
} }
@@ -184,7 +176,7 @@ module = (typeof module === 'undefined') ? {} : module;
return r; return r;
}; };
function findRoot (parent) { function findRoot(parent) {
if (!parent || !parent.id) { return Require.root; } if (!parent || !parent.id) { return Require.root; }
var pathParts = parent.id.split(/[\/|\\,]+/g); var pathParts = parent.id.split(/[\/|\\,]+/g);
pathParts.pop(); pathParts.pop();
@@ -199,20 +191,20 @@ module = (typeof module === 'undefined') ? {} : module;
Module.require = require; Module.require = require;
module.exports = Module; module.exports = Module;
function loadJSON (file) { function loadJSON(file) {
var json = JSON.parse(readFile(file)); var json = JSON.parse(readFile(file));
Require.cache[file] = json; Require.cache[file] = json;
return json; return json;
} }
function resolveAsNodeModule (id, root) { function resolveAsNodeModule(id, root) {
var base = [root, 'node_modules'].join('/'); var base = [root, 'node_modules'].join('/');
return resolveAsFile(id, base) || return resolveAsFile(id, base) ||
resolveAsDirectory(id, base) || resolveAsDirectory(id, base) ||
(root ? resolveAsNodeModule(id, new File(root).getParent()) : false); (root ? resolveAsNodeModule(id, new File(root).getParent()) : false);
} }
function resolveAsDirectory (id, root) { function resolveAsDirectory(id, root) {
var base = [root, id].join('/'); var base = [root, id].join('/');
var file = new File([base, 'package.json'].join('/')); var file = new File([base, 'package.json'].join('/'));
if (file.exists()) { if (file.exists()) {
@@ -232,7 +224,7 @@ module = (typeof module === 'undefined') ? {} : module;
return resolveAsFile('index.js', base); return resolveAsFile('index.js', base);
} }
function resolveAsFile (id, root, ext) { function resolveAsFile(id, root, ext) {
var file; var file;
if (id.length > 0 && id[0] === '/') { if (id.length > 0 && id[0] === '/') {
file = new File(normalizeName(id, ext)); file = new File(normalizeName(id, ext));
@@ -247,7 +239,7 @@ module = (typeof module === 'undefined') ? {} : module;
} }
} }
function resolveCoreModule (id, root) { function resolveCoreModule(id, root) {
var name = normalizeName(id); var name = normalizeName(id);
var classloader = java.lang.Thread.currentThread().getContextClassLoader(); var classloader = java.lang.Thread.currentThread().getContextClassLoader();
if (classloader.getResource(name)) { if (classloader.getResource(name)) {
@@ -255,8 +247,8 @@ module = (typeof module === 'undefined') ? {} : module;
} }
} }
function normalizeName (fileName, ext) { function normalizeName(fileName, ext) {
if(fileName.endsWith('.json')){ if (fileName.endsWith('.json')) {
return fileName; return fileName;
} }
var extension = ext || '.js'; var extension = ext || '.js';
@@ -266,7 +258,7 @@ module = (typeof module === 'undefined') ? {} : module;
return fileName + extension; return fileName + extension;
} }
function readFile (filename, core) { function readFile(filename, core) {
var input; var input;
try { try {
if (core) { if (core) {
@@ -282,7 +274,7 @@ module = (typeof module === 'undefined') ? {} : module;
} }
} }
function ModuleError (message, code, cause) { function ModuleError(message, code, cause) {
this.code = code || 'UNDEFINED'; this.code = code || 'UNDEFINED';
this.message = message || 'Error loading module'; this.message = message || 'Error loading module';
this.cause = cause; this.cause = cause;

View File

@@ -97,6 +97,7 @@ public class Mat extends org.opencv.core.Mat implements ResourceMonitor.Resource
if (!mReleased) { if (!mReleased) {
ResourceMonitor.onFinalize(this); ResourceMonitor.onFinalize(this);
super.release(); super.release();
mReleased = true;
} }
super.finalize(); super.finalize();
} }

View File

@@ -9,8 +9,6 @@ import com.afollestad.materialdialogs.MaterialDialog;
import org.opencv.android.InstallCallbackInterface; import org.opencv.android.InstallCallbackInterface;
import org.opencv.android.LoaderCallbackInterface; import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader; import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.imgproc.Imgproc;
/** /**
@@ -33,6 +31,8 @@ public class OpenCVHelper {
public static void release(@Nullable MatOfPoint mat) { public static void release(@Nullable MatOfPoint mat) {
if (mat == null) if (mat == null)
return; return;
mat.release(); mat.release();
} }

View File

@@ -452,7 +452,8 @@ public class ScriptRuntime {
} }
public static String getStackTrace(Throwable e, boolean printJavaStackTrace) { public static String getStackTrace(Throwable e, boolean printJavaStackTrace) {
StringBuilder scriptTrace = new StringBuilder(); String message = e.getMessage();
StringBuilder scriptTrace = new StringBuilder(message == null ? "" : message + "\n");
if (e instanceof RhinoException) { if (e instanceof RhinoException) {
RhinoException rhinoException = (RhinoException) e; RhinoException rhinoException = (RhinoException) e;
scriptTrace.append(rhinoException.details()).append("\n"); scriptTrace.append(rhinoException.details()).append("\n");
@@ -479,7 +480,7 @@ public class ScriptRuntime {
return scriptTrace.toString(); return scriptTrace.toString();
} catch (IOException e1) { } catch (IOException e1) {
e1.printStackTrace(); e1.printStackTrace();
return e.getMessage(); return message;
} }
} }

View File

@@ -9,6 +9,7 @@ import android.graphics.Matrix;
import android.media.Image; import android.media.Image;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.SystemClock;
import android.support.annotation.RequiresApi; import android.support.annotation.RequiresApi;
import android.util.Base64; import android.util.Base64;
import android.view.Display; import android.view.Display;
@@ -29,6 +30,7 @@ import com.stardust.pio.UncheckedIOException;
import com.stardust.util.ScreenMetrics; import com.stardust.util.ScreenMetrics;
import com.stardust.autojs.core.opencv.Mat; import com.stardust.autojs.core.opencv.Mat;
import org.opencv.core.Point; import org.opencv.core.Point;
import org.opencv.core.Rect; import org.opencv.core.Rect;
@@ -270,4 +272,12 @@ public class Images {
return point; return point;
} }
public Mat newMat() {
return new Mat();
}
public Mat newMat(Mat mat, Rect roi) {
return new Mat(mat, roi);
}
} }