简体   繁体   English

在缓冲的图像中查找具有公差的颜色

[英]Find color with tolerance in bufferedimage

I'm writing a method that will attempt to find a color in a bufferedImage. 我正在写一种方法,尝试在bufferedImage中查找颜色。 At the moment, the method works by taking a screencap, and then scanning the image for a specific color. 目前,该方法通过抓取屏幕截图,然后扫描图像中的特定颜色来工作。 Now I'd like to add some RGB tolerence, so if the user is trying to find color (1, 3, 5) with tolerance 1, any color +-1 R, B or G will return true. 现在,我想添加一些RGB容差,因此,如果用户尝试查找容差为1的颜色(1、3、5),则任何+ -1 R,B或G的颜色都将返回true。

I could solve this by first generating a arrayList of RGB values that work, and then for each pixel I could go through the array and check with each value. 我可以通过首先生成一个有效的RGB值的arrayList来解决此问题,然后对于每个像素,我可以遍历该数组并检查每个值。 The problem is that would probably get VERY slow for high tolerances on large images. 问题在于,对于大图像的高公差,可能会变得非常慢。

Is there a more efficient or possibly a built in way I can do this? 有没有一种我可以做到的更有效或内置的方式? Here is my method as it stands right now. 这是我目前的方法。 Thank you! 谢谢!

public static Point findColor(Box searchArea, int color){
    System.out.println("Test");
    BufferedImage image = generateScreenCap(searchArea);
    for (int i = 0; i < image.getWidth(); i++) {
        for (int j = 0; j < image.getHeight(); j++) {
            if((image.getRGB(i, j)*-1)==color){
                return new Point(i + searchArea.x1, j + searchArea.y1);
            }
        }
    }
    return new Point(-1, -1);
}

Edit: I'm using the int RGB values for all comparisons, so instead of Color[1, 1, 1], I use Color.getRGB() which returns a negative int which I convert to positive for end user simplicity. 编辑:我将int RGB值用于所有比较,所以我使用Color.getRGB()代替Color [1,1,1],它返回一个负整数,为了最终用户简化,我将其转换为正整数。

You need to compare RGB values and not the "whole" color if you want to have a custom tolerance. 如果要具有自定义公差,则需要比较RGB值,而不是“整个”颜色。 Here is the code, it is not tested, but you get the idea : 这是代码,未经测试,但是您可以理解:

public static Point findColor(Box searchArea, int r, int g, int b, int tolerance){
    System.out.println("Test");

    // Pre-calc RGB "tolerance" values out of the loop (min is 0 and max is 255)
    int minR = Math.max(r - tolerance, 0);
    int minG = Math.max(g - tolerance, 0);
    int minB = Math.max(b - tolerance, 0);
    int maxR = Math.min(r + tolerance, 255);
    int maxG = Math.min(g + tolerance, 255);
    int maxB = Math.min(b + tolerance, 255);

    BufferedImage image = generateScreenCap(searchArea);
    for (int i = 0; i < image.getWidth(); i++) {
        for (int j = 0; j < image.getHeight(); j++) {
            // get single RGB pixel
            int color = image.getRGB(i, j);

            // get individual RGB values of that pixel
            // (could use Java's Color class but this is probably a little faster)
            int red = (color >> 16) & 0x000000FF;
            int green = (color >>8 ) & 0x000000FF;
            int blue = (color) & 0x000000FF;  

            if ( (red >= minR && red <= maxR) &&
                 (green >= minG && green <= maxG) &&
                 (blue >= minB && blue <= maxB) ) 
                return new Point(i + searchArea.x1, j + searchArea.y1);
        }
    }
    return new Point(-1, -1);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM