fix: images.detectsColor() and images.pixel() cause "x > image.width" exception when image is landscape

This commit is contained in:
hyb1996
2018-01-27 09:43:22 +08:00
parent 1e8183f756
commit 771511e939
3 changed files with 23 additions and 29 deletions

View File

@@ -29,19 +29,25 @@ import java.util.concurrent.TimeUnit;
@RequiresApi(api = Build.VERSION_CODES.KITKAT) @RequiresApi(api = Build.VERSION_CODES.KITKAT)
public class ColorFinder { public class ColorFinder {
public static Point findColorEquals(ImageWrapper imageWrapper, int color) { private ScreenMetrics mScreenMetrics;
public ColorFinder(ScreenMetrics screenMetrics) {
mScreenMetrics = screenMetrics;
}
public Point findColorEquals(ImageWrapper imageWrapper, int color) {
return findColorEquals(imageWrapper, color, null); return findColorEquals(imageWrapper, color, null);
} }
public static Point findColorEquals(ImageWrapper imageWrapper, int color, Rect region) { public Point findColorEquals(ImageWrapper imageWrapper, int color, Rect region) {
return findColor(imageWrapper, color, 0, region); return findColor(imageWrapper, color, 0, region);
} }
public static Point findColor(ImageWrapper imageWrapper, int color, int threshold) { public Point findColor(ImageWrapper imageWrapper, int color, int threshold) {
return findColor(imageWrapper, color, threshold, null); return findColor(imageWrapper, color, threshold, null);
} }
public static Point findColor(ImageWrapper imageWrapper, int color, int threshold, Rect region) { public Point findColor(ImageWrapper imageWrapper, int color, int threshold, Rect region) {
Point[] points = findAllColors(imageWrapper, color, threshold, region); Point[] points = findAllColors(imageWrapper, color, threshold, region);
if (points.length == 0) { if (points.length == 0) {
return null; return null;
@@ -49,7 +55,7 @@ public class ColorFinder {
return points[0]; return points[0];
} }
public static Point[] findAllColors(ImageWrapper image, int color, int threshold, Rect rect) { public Point[] findAllColors(ImageWrapper image, int color, int threshold, Rect rect) {
Mat bi = new Mat(); Mat bi = new Mat();
Scalar lowerBound = new Scalar(Color.red(color) - threshold, Color.green(color) - threshold, Scalar lowerBound = new Scalar(Color.red(color) - threshold, Color.green(color) - threshold,
Color.blue(color) - threshold, 255); Color.blue(color) - threshold, 255);
@@ -68,8 +74,8 @@ public class ColorFinder {
Point[] points = new MatOfPoint(nonZeroPos).toArray(); Point[] points = new MatOfPoint(nonZeroPos).toArray();
if (rect != null) { if (rect != null) {
for (int i = 0; i < points.length; i++) { for (int i = 0; i < points.length; i++) {
points[i].x += rect.x; points[i].x = mScreenMetrics.scaleX((int) (points[i].x + rect.x));
points[i].y += rect.y; points[i].y = mScreenMetrics.scaleX((int) (points[i].y + rect.y));
} }
} }
return points; return points;

View File

@@ -53,6 +53,7 @@ public class Images {
private Display mDisplay; private Display mDisplay;
private Image mPreCapture; private Image mPreCapture;
private ImageWrapper mPreCaptureImage; private ImageWrapper mPreCaptureImage;
private ScreenMetrics mScreenMetrics;
@ScriptVariable @ScriptVariable
public final ColorFinder colorFinder; public final ColorFinder colorFinder;
@@ -62,7 +63,8 @@ public class Images {
mScreenCaptureRequester = screenCaptureRequester; mScreenCaptureRequester = screenCaptureRequester;
mContext = context; mContext = context;
mDisplay = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); mDisplay = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
colorFinder = new ColorFinder(); mScreenMetrics = mScriptRuntime.getScreenMetrics();
colorFinder = new ColorFinder(mScreenMetrics);
} }
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@@ -135,8 +137,6 @@ public class Images {
if (image == null) { if (image == null) {
throw new NullPointerException("image = null"); throw new NullPointerException("image = null");
} }
x = ScreenMetrics.rescaleX(x, image.getWidth());
y = ScreenMetrics.rescaleY(y, image.getHeight());
return image.pixel(x, y); return image.pixel(x, y);
} }
@@ -212,8 +212,8 @@ public class Images {
org.opencv.core.Point point = TemplateMatching.fastTemplateMatching(src, template.getMat(), TemplateMatching.MATCHING_METHOD_DEFAULT, org.opencv.core.Point point = TemplateMatching.fastTemplateMatching(src, template.getMat(), TemplateMatching.MATCHING_METHOD_DEFAULT,
weakThreshold, threshold, maxLevel); weakThreshold, threshold, maxLevel);
if (point != null && rect != null) { if (point != null && rect != null) {
point.x += rect.x; point.x = mScreenMetrics.scaleX((int) (point.x + rect.x));
point.y += rect.y; point.y = mScreenMetrics.scaleX((int) (point.y + rect.y));
} }
return point; return point;
} }

View File

@@ -18,7 +18,7 @@ public class ScreenMetrics {
private static Display display; private static Display display;
public static void initIfNeeded(Activity activity) { public static void initIfNeeded(Activity activity) {
if(initialized) if (initialized)
return; return;
DisplayMetrics metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics); activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
@@ -86,17 +86,11 @@ public class ScreenMetrics {
} }
public int scaleX(int x) { public int scaleX(int x) {
if (display.getRotation() == Surface.ROTATION_0 || display.getRotation() == Surface.ROTATION_180) return scaleX(x, mDesignWidth);
return scaleX(x, mDesignWidth);
else
return scaleY(x, mDesignWidth);
} }
public int scaleY(int y) { public int scaleY(int y) {
if (display.getRotation() == Surface.ROTATION_0 || display.getRotation() == Surface.ROTATION_180) return scaleY(y, mDesignHeight);
return scaleY(y, mDesignHeight);
else
return scaleX(y, mDesignHeight);
} }
@@ -106,17 +100,11 @@ public class ScreenMetrics {
} }
public int rescaleX(int x) { public int rescaleX(int x) {
if (display.getRotation() == Surface.ROTATION_0 || display.getRotation() == Surface.ROTATION_180) return rescaleX(x, mDesignWidth);
return rescaleX(x, mDesignWidth);
else
return rescaleY(x, mDesignWidth);
} }
public int rescaleY(int y) { public int rescaleY(int y) {
if (display.getRotation() == Surface.ROTATION_0 || display.getRotation() == Surface.ROTATION_180) return rescaleY(y, mDesignHeight);
return rescaleY(y, mDesignHeight);
else
return rescaleX(y, mDesignHeight);
} }
} }