0

I'm trying to take a screenshot and then look through it for a pixel that has a certain color. Firstly, I tried to just print the color of an image at a certain xy coordinate but I could not even do that. What am I doing wrong?

static int ScreenWidth;
static int ScreenHeight;
static Robot robot;

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic 
    callibrateScreenSize();
    findSquares();
    //takeScreenShot();

    try {
        Thread.sleep(1000);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

public static void callibrateScreenSize() {

    try {
        Rectangle captureSize = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        ScreenWidth = captureSize.width;
        ScreenHeight = captureSize.height;
        System.out.println("Width is " + ScreenWidth);
        System.out.println("Height is " + ScreenHeight);
    } catch (Exception e) {
        e.printStackTrace();
    }
    //return null;
}

public static BufferedImage takeScreenShot() {
    Rectangle captureSize = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
    BufferedImage image = robot.createScreenCapture(captureSize);
    return image;
}

public static void findSquares() {
    System.out.println(takeScreenShot().getRGB(5,5));
}

Thanks!

2 Answers2

2

You can use BufferedImage#getRGB or byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData() to get the pixel data. getRBG is more convenient, but is typically slower than getting the pixel array

getRGB packs the pixel data into an int, getData will return the RGB(A) in each entry of the array (R = n; G = n+1; B=n+2(, A=n+3)), so will need to process this yourself

You can use java.awt.Color, which allows you to access the RGB values of the color, pack it as a int value or convert an int to a Color

Color color = new Color(bufferedImage.getRGB(0, 0), true);
int redColor = Color.RED.getRGB();

The answer to this question provides an example of dealing with the byte[] pixel data

Basically, you will need to loop over the data, comparing the values in the image to the value you are after, either directly (comparing the red, green and blue values) or indirectly, comparing the packed int or Color values.

Personally, I'd grab the pixel data, convert each element to an int and compare it with a previously packed int from a Color object, this creates the less number of short lived objects and should be reasonably efficient

You can take a look at this answer which use getRGB to get the red, green, blue values from a given pixel

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Ohh okay so if I want to test every pixel in a picture I can set up a loop and cycle through all the pixels by using `Color` and testing color? My only question now is why does printing out a `getRGB()` not work? Also how do I test for a very specific color? – Benjamin Spiegel Feb 05 '15 at 03:45
  • `getRGB` returns an `int` (packed pixel), as I said, I would start by creating a `Color` of the color you want to find and use `Color#getRGB` to return the packed `int` value for that color. It would then compare the result with the values from `BufferedImage#getRGB` – MadProgrammer Feb 05 '15 at 03:52
  • Why am I unable to run this in a method? `Rectangle captureSize = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); BufferedImage image = robot.createScreenCapture(captureSize); Color color = new Color(image.getRGB(0, 0), true);` – Benjamin Spiegel Feb 05 '15 at 04:00
  • Where do you create an instance of `Robot`? – MadProgrammer Feb 05 '15 at 04:02
  • At the beginning of the class. Right now I'm trying to use getRBG() and checking the color using bit shifting and masking as per a friends advice – Benjamin Spiegel Feb 05 '15 at 04:07
  • Don't see where you initialise an instance of `Robot`, I see where you declare a variable of type `Robot`, but you never initialise it. I run your code (after I initialised `robot`) and it works fine – MadProgrammer Feb 05 '15 at 04:20
0

Here's something I wrote a while ago using the Robot class. It returns an array of the screen wherever the screen is white, it was not very computationally expensive for my application, but I found probing the values individually using robot was. At first I didn't even read your question, but looking back, I think this will help you A LOT. Good luck. And then I saw the original post date...

public boolean[][] raster() throws AWTException, IOException{
   boolean[][] filled= new boolean[720][480];
  BufferedImage image = new Robot().createScreenCapture(new Rectangle(0,0,720,480));
//accepts (xCoord,yCoord, width, height) of screen
    for (int n =0; n<720; n++){
          for (int m=0; m<480; m++){
              if(new Color(image.getRGB(n, m)).getRed()<254){   
//can check any rgb value, I just chose red in this case to check for white pixels    
                  filled[n][m]=true;
              }
          }
        }
      return filled;
}