新增 opencv懒加载

This commit is contained in:
hyb1996
2018-11-02 00:48:13 +08:00
parent d8d02a1137
commit 248d698708
9 changed files with 99 additions and 65 deletions

View File

@@ -36,6 +36,14 @@ ui.layout(
function setImage(img) {
ui.run(() => {
ui.img.setImageBitmap(img.bitmap);
var oldImg = currentImg;
//不能立即回收currentImg因为此时img控件还在使用它应该在下次消息循环再回收它
ui.post(()=>{
if(oldImg != null){
oldImg.recycle();
}
});
currentImg = img;
});
}
@@ -52,10 +60,6 @@ function processImg(process) {
}
//处理图片
var result = process(logo);
if(currentImg != null){
currentImg.recycle();
}
currentImg = result;
//把处理后的图片设置到图片控件中
setImage(result);
}, 0);

View File

@@ -9,7 +9,6 @@ import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import com.stardust.autojs.core.opencv.OpenCVHelper;
import com.xcy8.ads.listener.LoadAdListener;
import com.xcy8.ads.view.FullScreenAdView;
@@ -30,7 +29,7 @@ public class SplashActivity extends BaseActivity {
public static final String FORCE_SHOW_AD = "forceShowAd";
private static final String LOG_TAG = SplashActivity.class.getSimpleName();
private static final long INIT_TIMEOUT = 1500;
private static final long INIT_TIMEOUT = 1000;
private boolean mCanEnterNextActivity = false;
@@ -47,7 +46,6 @@ public class SplashActivity extends BaseActivity {
super.onCreate(savedInstanceState);
init();
boolean forceShowAd = getIntent().getBooleanExtra(FORCE_SHOW_AD, false);
final long millis = SystemClock.uptimeMillis();
if (!forceShowAd && !Pref.shouldShowAd()) {
mFullScreenAdView.setVisibility(View.INVISIBLE);
} else {
@@ -55,14 +53,7 @@ public class SplashActivity extends BaseActivity {
fetchSplashAD();
}
}
OpenCVHelper.initIfNeeded(this, () -> {
long delay = INIT_TIMEOUT - (SystemClock.uptimeMillis() - millis);
if (delay <= 0) {
enterNextActivity();
return;
}
mHandler.postDelayed(SplashActivity.this::enterNextActivity, delay);
});
mHandler.postDelayed(SplashActivity.this::enterNextActivity, INIT_TIMEOUT);
}
private void init() {

View File

@@ -66,6 +66,7 @@ module.exports = function (runtime, scope) {
}
images.threshold = function (img, threshold, maxVal, type) {
initIfNeeded();
var mat = new Mat();
type = type || "BINARY";
type = Imgproc["THRESH_" + type];
@@ -74,6 +75,7 @@ module.exports = function (runtime, scope) {
}
images.inRange = function (img, lowerBound, upperBound) {
initIfNeeded();
var lb, ub;
if (typeof (lowerBound) == 'string') {
if (typeof (upperBound) == 'string') {
@@ -99,6 +101,7 @@ module.exports = function (runtime, scope) {
images.adaptiveThreshold = function(img, maxValue, adaptiveMethod, thresholdType, blockSize, C){
initIfNeeded();
var mat = new Mat();
adaptiveMethod = Imgproc["ADAPTIVE_THRESH_" + adaptiveMethod];
thresholdType = Imgproc["THRESH_" + thresholdType];
@@ -107,6 +110,7 @@ module.exports = function (runtime, scope) {
}
images.blur = function (img, size, point, type) {
initIfNeeded();
var mat = new Mat();
size = newSize(size);
type = Imgproc["BORDER_" + (type || "CONSTANT")];
@@ -119,6 +123,7 @@ module.exports = function (runtime, scope) {
}
images.medianBlur = function (img, size) {
initIfNeeded();
var mat = new Mat();
Imgproc.medianBlur(img.mat, mat, size);
return images.matToImage(mat);
@@ -126,6 +131,7 @@ module.exports = function (runtime, scope) {
images.gaussianBlur = function (img, size, sigmaX, sigmaY, type) {
initIfNeeded();
var mat = new Mat();
size = newSize(size);
sigmaX = sigmaX == undefined ? 0 : sigmaX;
@@ -136,6 +142,7 @@ module.exports = function (runtime, scope) {
}
images.cvtColor = function (img, code, dstCn) {
initIfNeeded();
var mat = new Mat();
code = Imgproc["COLOR_" + code];
if (dstCn == undefined) {
@@ -147,6 +154,7 @@ module.exports = function (runtime, scope) {
}
images.findCircles = function(grayImg, options) {
initIfNeeded();
options = options || {};
var mat = options.region == undefined ? grayImg.mat : new Mat(grayImg.mat, buildRegion(options.region, grayImg));
var resultMat = new Mat()
@@ -176,6 +184,7 @@ module.exports = function (runtime, scope) {
}
images.resize = function(img, size, interpolation) {
initIfNeeded();
var mat = new Mat();
interpolation = Imgproc["INTER_" + (interpolation || "LINEAR")];
Imgproc.resize(img.mat, mat, newSize(size), 0, 0, interpolation);
@@ -183,6 +192,7 @@ module.exports = function (runtime, scope) {
}
images.scale = function(img, fx, fy, interpolation) {
initIfNeeded();
var mat = new Mat();
interpolation = Imgproc["INTER_" + (interpolation || "LINEAR")];
Imgproc.resize(img.mat, mat, newSize([0, 0]), fx, fy, interpolation);
@@ -190,6 +200,7 @@ module.exports = function (runtime, scope) {
}
images.rotate = function(img, degree, x, y) {
initIfNeeded();
if(x == undefined){
x = img.width / 2;
}
@@ -200,6 +211,7 @@ module.exports = function (runtime, scope) {
}
images.concat = function(img1, img2, direction, rect1, rect2) {
initIfNeeded();
direction = direction || "right";
rect1 = buildRegion(rect1, img1);
rect2 = buildRegion(rect2, img1);
@@ -207,6 +219,7 @@ module.exports = function (runtime, scope) {
}
images.detectsColor = function (img, color, x, y, threshold, algorithm) {
initIfNeeded();
color = parseColor(color);
algorithm = algorithm || "diff";
threshold = threshold || defaultColorThreshold;
@@ -216,6 +229,7 @@ module.exports = function (runtime, scope) {
}
images.findColor = function (img, color, options) {
initIfNeeded();
color = parseColor(color);
options = options || {};
var region = options.region || [];
@@ -246,6 +260,7 @@ module.exports = function (runtime, scope) {
}
images.findAllPointsForColor = function (img, color, options) {
initIfNeeded();
color = parseColor(color);
options = options || {};
if (options.similarity) {
@@ -261,6 +276,7 @@ module.exports = function (runtime, scope) {
}
images.findMultiColors = function (img, firstColor, paths, options) {
initIfNeeded();
options = options || {};
firstColor = parseColor(firstColor);
var list = java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE, paths.length * 3);
@@ -276,6 +292,7 @@ module.exports = function (runtime, scope) {
}
images.findImage = function (img, template, options) {
initIfNeeded();
options = options || {};
var threshold = options.threshold || 0.9;
var maxLevel = -1;
@@ -333,6 +350,7 @@ module.exports = function (runtime, scope) {
}
images.matToImage = function(img){
initIfNeeded();
return Image.ofMat(img);
}
@@ -389,6 +407,10 @@ module.exports = function (runtime, scope) {
}
return new Size(size[0], size[1]);
}
function initIfNeeded(){
javaImages.initOpenCvIfNeeded();
}
scope.__asGlobal__(images, ['requestScreenCapture', 'captureScreen', 'findImage', 'findImageInRegion', 'findColor', 'findColorInRegion', 'findColorEquals', 'findMultiColors']);

View File

@@ -94,8 +94,11 @@ module.exports = function (runtime, global) {
}
ui.post = function (action, delay) {
delay = delay || 0;
runtime.getUiHandler().postDelayed(wrapUiAction(action), delay);
if(delay == undefined){
runtime.getUiHandler().post(wrapUiAction(action));
}else{
runtime.getUiHandler().postDelayed(wrapUiAction(action), delay);
}
}
ui.statusBarColor = function (color) {

View File

@@ -87,12 +87,6 @@ public abstract class AutoJs {
protected void init() {
addAccessibilityServiceDelegates();
registerActivityLifecycleCallbacks();
try {
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, mContext, new BaseLoaderCallback(mContext) {
});
} catch (Exception e) {
e.printStackTrace();
}
ResourceMonitor.setExceptionCreator(resource -> {
Exception exception;
if (org.mozilla.javascript.Context.getCurrentContext() != null) {

View File

@@ -1,10 +1,11 @@
package com.stardust.autojs.core.opencv;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.Log;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.app.DialogUtils;
import org.opencv.android.InstallCallbackInterface;
import org.opencv.android.LoaderCallbackInterface;
@@ -22,7 +23,7 @@ public class OpenCVHelper {
}
private static final String LOG_TAG = "OpenCVHelper";
private static boolean mInitialized = false;
private static boolean sInitialized = false;
public static MatOfPoint newMatOfPoint(Mat mat){
return new MatOfPoint(mat);
@@ -31,25 +32,26 @@ public class OpenCVHelper {
public static void release(@Nullable MatOfPoint mat) {
if (mat == null)
return;
mat.release();
}
public static void release(@Nullable Mat mat) {
if (mat == null)
return;
mat.release();
}
public static void initIfNeeded(Activity activity, InitializeCallback callback) {
if (mInitialized) {
public synchronized static boolean isInitialized() {
return sInitialized;
}
public synchronized static void initIfNeeded(Context context, InitializeCallback callback) {
if (sInitialized) {
callback.onInitFinish();
return;
}
mInitialized = true;
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, activity.getApplicationContext(), new LoaderCallback(activity) {
sInitialized = true;
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, context.getApplicationContext(), new LoaderCallback(context) {
@Override
protected void finish() {
@@ -60,10 +62,10 @@ public class OpenCVHelper {
public static class LoaderCallback implements LoaderCallbackInterface {
private Activity mActivity;
private Context mContext;
public LoaderCallback(Activity activity) {
this.mActivity = activity;
public LoaderCallback(Context context) {
this.mContext = context;
}
public void onManagerConnected(int status) {
@@ -74,23 +76,23 @@ public class OpenCVHelper {
case 1:
default:
Log.e(LOG_TAG, "OpenCV loading failed!");
new MaterialDialog.Builder(mActivity)
DialogUtils.showDialog(new MaterialDialog.Builder(mContext)
.title("OpenCV error")
.content("OpenCV was not initialised correctly. Application will be shut down")
.cancelable(false)
.positiveText("OK")
.onPositive((dialog, which) -> finish())
.show();
.build());
break;
case 2:
Log.e(LOG_TAG, "Package installation failed!");
new MaterialDialog.Builder(mActivity)
DialogUtils.showDialog(new MaterialDialog.Builder(mContext)
.title("OpenCV Manager")
.content("Package installation failed!")
.cancelable(false)
.positiveText("OK")
.onPositive((dialog, which) -> finish())
.show();
.build());
break;
case 3:
Log.d(LOG_TAG, "OpenCV library instalation was canceled by user");
@@ -98,13 +100,13 @@ public class OpenCVHelper {
break;
case 4:
Log.d(LOG_TAG, "OpenCV Manager Service is uncompatible with this app!");
new MaterialDialog.Builder(mActivity)
DialogUtils.showDialog(new MaterialDialog.Builder(mContext)
.title("OpenCV Manager")
.content("OpenCV Manager service is incompatible with this app. Try to update it via Google Play.")
.cancelable(false)
.positiveText("OK")
.onPositive((dialog, which) -> finish())
.show();
.build());
}
}
@@ -112,7 +114,7 @@ public class OpenCVHelper {
public void onPackageInstall(int operation, final InstallCallbackInterface callback) {
switch (operation) {
case 0:
new MaterialDialog.Builder(mActivity)
DialogUtils.showDialog(new MaterialDialog.Builder(mContext)
.title("Package not found")
.content(callback.getPackageName() + " package was not found! Try to install it?")
.cancelable(false)
@@ -120,10 +122,10 @@ public class OpenCVHelper {
.onPositive((dialog, which) -> callback.install())
.negativeText("No")
.onNegative(((dialog, which) -> callback.cancel()))
.show();
.build());
break;
case 1:
new MaterialDialog.Builder(mActivity)
DialogUtils.showDialog(new MaterialDialog.Builder(mContext)
.title("OpenCV is not ready")
.content("Installation is in progress. Wait or exit?")
.cancelable(false)
@@ -131,7 +133,7 @@ public class OpenCVHelper {
.onPositive((dialog, which) -> callback.wait_install())
.negativeText("Exit")
.onNegative(((dialog, which) -> callback.cancel()))
.show();
.build());
default:
finish();
}
@@ -139,7 +141,6 @@ public class OpenCVHelper {
}
protected void finish() {
mActivity.finish();
}
}

View File

@@ -11,6 +11,7 @@ import android.graphics.Paint;
import android.media.Image;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.RequiresApi;
import android.util.Base64;
import android.view.Gravity;
@@ -55,6 +56,7 @@ public class Images {
private Image mPreCapture;
private ImageWrapper mPreCaptureImage;
private ScreenMetrics mScreenMetrics;
private volatile boolean mOpenCvInitialized = false;
@ScriptVariable
public final ColorFinder colorFinder;
@@ -148,7 +150,7 @@ public class Images {
}
public static ImageWrapper concat(ImageWrapper img1, Rect rect1, ImageWrapper img2, Rect rect2, int direction) {
if(!Arrays.asList(Gravity.LEFT, Gravity.RIGHT, Gravity.TOP, Gravity.BOTTOM).contains(direction)){
if (!Arrays.asList(Gravity.LEFT, Gravity.RIGHT, Gravity.TOP, Gravity.BOTTOM).contains(direction)) {
throw new IllegalArgumentException("unknown direction " + direction);
}
int width;
@@ -283,6 +285,7 @@ public class Images {
}
public Point findImage(ImageWrapper image, ImageWrapper template, float weakThreshold, float threshold, Rect rect, int maxLevel) {
initOpenCvIfNeeded();
if (image == null)
throw new NullPointerException("image = null");
if (template == null)
@@ -315,4 +318,27 @@ public class Images {
return new Mat(mat, roi);
}
public void initOpenCvIfNeeded() {
if (mOpenCvInitialized || OpenCVHelper.isInitialized()) {
return;
}
Activity currentActivity = mScriptRuntime.app.getCurrentActivity();
Context context = currentActivity == null ? mContext : currentActivity;
mScriptRuntime.console.info("opencv initializing");
if (Looper.myLooper() == Looper.getMainLooper()) {
OpenCVHelper.initIfNeeded(context, () -> {
mOpenCvInitialized = true;
mScriptRuntime.console.info("opencv initialized");
});
} else {
VolatileDispose<Boolean> result = new VolatileDispose<>();
OpenCVHelper.initIfNeeded(context, () -> {
mOpenCvInitialized = true;
result.setAndNotify(true);
mScriptRuntime.console.info("opencv initialized");
});
result.blockedGet();
}
}
}

View File

@@ -16,7 +16,7 @@ public final class ResourceMonitor {
private static final ConcurrentHashMap<Class<?>, SparseArray<Exception>> mResources = new ConcurrentHashMap<>();
private static Handler sHandler;
private static boolean mEnabled = BuildConfig.DEBUG;
private static boolean sEnabled = BuildConfig.DEBUG;
private static ExceptionCreator sExceptionCreator;
private static UnclosedResourceDetectedHandler sUnclosedResourceDetectedHandler;
@@ -29,7 +29,7 @@ public final class ResourceMonitor {
}
public static void onOpen(ResourceMonitor.Resource resource) {
if (!mEnabled) {
if (!sEnabled) {
return;
}
SparseArray<Exception> map = mResources.get(resource.getClass());
@@ -49,7 +49,7 @@ public final class ResourceMonitor {
}
public static void onClose(ResourceMonitor.Resource resource) {
if (!mEnabled) {
if (!sEnabled) {
return;
}
SparseArray map = mResources.get(resource.getClass());
@@ -59,7 +59,7 @@ public final class ResourceMonitor {
}
public static void onFinalize(ResourceMonitor.Resource resource) {
if (!mEnabled) {
if (!sEnabled) {
return;
}
SparseArray<Exception> map = mResources.get(resource.getClass());
@@ -88,11 +88,11 @@ public final class ResourceMonitor {
}
public static boolean isEnabled() {
return mEnabled;
return sEnabled;
}
public static void setEnabled(boolean mEnabled) {
ResourceMonitor.mEnabled = mEnabled;
ResourceMonitor.sEnabled = mEnabled;
}
public static final class UnclosedResourceException extends RuntimeException {

View File

@@ -6,7 +6,6 @@ import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
@@ -16,7 +15,6 @@ import android.widget.Toast;
import com.stardust.auojs.inrt.autojs.AutoJs;
import com.stardust.auojs.inrt.launch.GlobalProjectLauncher;
import com.stardust.autojs.core.opencv.OpenCVHelper;
import java.util.ArrayList;
import java.util.List;
@@ -38,16 +36,11 @@ public class SplashActivity extends AppCompatActivity {
setContentView(R.layout.activity_splash);
TextView slug = findViewById(R.id.slug);
slug.setTypeface(Typeface.createFromAsset(getAssets(), "roboto_medium.ttf"));
final long millis = SystemClock.uptimeMillis();
OpenCVHelper.initIfNeeded(this, () -> {
long delay = INIT_TIMEOUT - (SystemClock.uptimeMillis() - millis);
if (!Pref.isFirstUsing() || delay <= 0) {
main();
return;
}
new Handler().postDelayed(SplashActivity.this::main, delay);
});
if (!Pref.isFirstUsing()) {
main();
}else {
new Handler().postDelayed(SplashActivity.this::main, INIT_TIMEOUT);
}
}
private void main() {