Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a faster way to get the colors in a screen-shot?

I have piece of code, and what it does is find the colors of an image (or section of the screen) and if the R G and B color's are greater than 127 it put's a 1 in the corresponding position of a 2D int array. Here is the segment I have now, but it is obviously extremely slow. Is there a better way to do this?

private void traceImage(){
    try{
        Robot r = new Robot();
        b = new int[470][338];
        for(int y = 597; y < 597+469; y++)
        {
            for(int x = 570; x < 570+337; x++)
            {
                if(r.getPixelColor(x,y).getRed() > 127 &&
                   r.getPixelColor(x,y).getGreen() > 127 && 
                   r.getPixelColor(x,y).getBlue() > 127)
                {
                    b[y-597][x-570] = 1;
                }
                else
                {
                    b[y-597][x-570] = 0;
                }
            }
        }
    }
    catch(Exception ex){System.out.println(ex.toString());}
}

There must be a faster way to do this using the values above. b is the int array and it is initialized in this segment. r is a robot that I use to find the color of the pixel on the screen. x and y should be self explanatory.

Thanks Mikera! This is the end result I got based on your answer:

private void traceActionPerformed(java.awt.event.ActionEvent evt) {
    try{
        Robot r = new Robot();
        BufferedImage image = r.createScreenCapture(new Rectangle(597,570,470,337));
        b = new int[image.getWidth()][image.getHeight()];
        for(int y=0;y<image.getWidth();y++){
            for(int x=0;x<image.getHeight();x++){
                if(image.getRGB(y,x)==-1){
                    b[y][x]=0;
                }
                else{
                    b[y][x]=1;                 
                }
            }
        }
        System.out.println("Done");
    }
    catch(Exception ex){System.out.println(ex.toString());}
}

The -1 in the if else statement apparently finds the value of black pixels like I wanted.

like image 394
jocopa3 Avatar asked Oct 07 '22 19:10

jocopa3


1 Answers

You should use Robot.createScreenCapture() to capture the entire subimage in one go.

Then you will be able to query the individual pixels in the subimage much faster, e.g. using BufferedImage.getRGB(x,y)

Interestingly your specific operation has a very fast bitwise implementation: just do ((rgb & 0x808080) == 0x808080)

like image 91
mikera Avatar answered Oct 10 '22 07:10

mikera