简体   繁体   中英

Getting Pixel Values from Byte Array

Im having trouble getting pixel data.

My program takes screenshots, every loop it will store the previous screenshot.

My goal is to do a comparison at the pixel level between the current screenshot and the old one.

Ive ran this code which tells me what format the screenshots are in: System.out.println(image.getType());

The output of this (for my program) is 1 meaning its a BufferedImage.TYPE_INT_RGB

From what ive read, the types determine what order the pixel values are in the byte array.

I'm using this code to convert my Buffered image to a byte array (The buffered image is created using awt.Robot class):

public byte[] convertToByteArray(BufferedImage img){
        byte[] imageInByte = null;
        try {



            // convert BufferedImage to byte array
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(img, "png", baos);
            baos.flush();
            imageInByte = baos.toByteArray();
            baos.close();

        } catch (IOException ex) {
            Logger.getLogger(OverlayWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
        return imageInByte;
}

Finally i use a comparison method to check the byte array. For now this only prints the color values of the array:

  final byte[] pixels = convertToByteArray(image);
  final int pixelLength = 3;
        for (int pixel = 0, row = 0, col = 0; pixel < 1; pixel += pixelLength) {
        int argb = 0;
        argb += -16777216; // 255 alpha
        argb += ((int) pixels[pixel] & 0xff); // blue
        argb += (((int) pixels[pixel + 1] & 0xff) << 8); // green
        argb += (((int) pixels[pixel + 2] & 0xff) << 16); // red


        int r = (argb >> 16) & 0xff, g = (argb >> 8)& 0xff, b = argb & 0xff;
        System.out.println("R = " + r);
        System.out.println("G = " + g);
        System.out.println("B = " +  b);

        col++;
        if (col == width) {
           col = 0;
           row++;
        }




     }

My issue with this code is that even though i take a screenshot of a solid color, the pixel values are all over the place. Im expecting each pixel to have the same color values.

-Edit-

I'm avoiding using getRGB for performance reasons. Iterating through two large images calling getRGB each time is very costly in my application.

The easiest way to access the pixels values in a BufferedImage is to use the Raster:

BufferedImage image = ...
for (int y=0 ; y < image.getHeight() ; y++)
    for (int x=0 ; x < image.getWidth() ; x++)
        for (int c=0 ; c < image.getRaster().getNumBands() ; c++)
            final int value = image.getRaster().getSample(x, y, c) ; // Returns the value of the channel C of the pixel (x,y)

The raster will take care of the encoding for you, making it the easiest way to access the pixel values. However, the fastest way is to use the DataBuffer, but then you have to manage all the encodings.

/* This method takes a BufferedImage encoded with TYPE_INT_ARGB and copies the pixel values into an image encoded with TYPE_4BYTE_ABGR.*/
public static void IntToByte(BufferedImage source, BufferedImage result)
    {
    final byte[] bb = ((DataBufferByte)result.getRaster().getDataBuffer()).getData() ;
    final int[] ib  = ((DataBufferInt)source.getRaster().getDataBuffer()).getData() ;

    switch ( source.getType() )
        {
        case BufferedImage.TYPE_INT_ARGB :
            for (int i=0, b=0 ; i < ib.length ; i++, b+=4)
                {
                int p   = ib[i] ;
                bb[b]   = (byte)((p & 0xFF000000) >> 24) ;
                bb[b+3] = (byte)((p & 0xFF0000) >> 16) ;
                bb[b+2] = (byte)((p & 0xFF00) >> 8) ;
                bb[b+1] = (byte)( p & 0xFF) ;
                }
            break ;
        // Many other case to manage...
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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