Get color of each pixel of an image using BufferedImages
Asked Answered
C

6

28

I am trying to get every single color of every single pixel of an image. My idea was following:

int[] pixels;
BufferedImage image;

image = ImageIO.read(this.getClass.getResources("image.png");
int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();

Is that right? I can't even check what the "pixels" array contains, because i get following error:

java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt

I just would like to receive the color of every pixel in an array, how do i achieve that?

Capful answered 13/3, 2014 at 21:29 Comment(0)
A
45
import java.io.*;
import java.awt.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;

public class GetPixelColor {
    public static void main(String args[]) throws IOException {
        File file = new File("your_file.jpg");
        BufferedImage image = ImageIO.read(file);
        // Getting pixel color by position x and y 
        int clr = image.getRGB(x, y);
        int red =   (clr & 0x00ff0000) >> 16;
        int green = (clr & 0x0000ff00) >> 8;
        int blue =   clr & 0x000000ff;
        System.out.println("Red Color value = " + red);
        System.out.println("Green Color value = " + green);
        System.out.println("Blue Color value = " + blue);
    }
}

Of course, you have to add a for loop for all pixels.

Absorbent answered 13/3, 2014 at 22:0 Comment(6)
sorry, i am completely new to this: i've seen that before, but what does this ">> 16" or ">> 8" ? Could you explain the line: int red = (clr & 0x00ff0000) >> 16; Thanks!Capful
@Capful The pixel/color is returned as a packed int, meaning that the RGBA values form individual bytes of the int. Basically BlackShadow is using bit shifting to extract the individual pixels. You could do the same thing with Color color = new Color(clr, true) and use the Color API to extract the components, which, IMHO is much easier and safer ;)Penstock
Thanks guys, i always see people coding with these shifting methods and i never quite understood what the hell they were doingCapful
>>8 : right shift by 8 position, suppose that red = 00000000 00001111 , red>>16 means 11111111 00000000 , (00001111 disappeared )Absorbent
@SriP In case you were still wondering, you create two nested for loops (one for x and one for y) with x going from 0 to the width of the image and y going from 0 to the height of the image, then plug that in for x and y in Black Shadow's code.Tessietessier
Ab example of those loops would be java for (int i = 0; i < ss.getHeight(); i++) { for (int j = 0; j < ss.getWidth(); j++) { int clr = ss.getRGB(i, j); int red = (clr & 0x00ff0000) >> 16; int green = (clr & 0x0000ff00) >> 8; int blue = clr & 0x000000ff; } }Alliterate
T
8

The problem (also with the answer that was linked from the first answer) is that you hardly ever know what exact type your buffered image will be after reading it with ImageIO. It could contain a DataBufferByte or a DataBufferInt. You may deduce it in some cases via BufferedImage#getType(), but in the worst case, it has type TYPE_CUSTOM, and then you can only fall back to some instanceof tests.

However, you can convert your image into a BufferedImage that is guaranteed to have a DataBufferInt with ARGB values - namely with something like

public static BufferedImage convertToARGB(BufferedImage image)
{
    BufferedImage newImage = new BufferedImage(
        image.getWidth(), image.getHeight(),
        BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = newImage.createGraphics();
    g.drawImage(image, 0, 0, null);
    g.dispose();
    return newImage;
}

Otherwise, you can call image.getRGB(x,y), which may perform the required conversions on the fly.

BTW: Note that obtaining the data buffer of a BufferedImage may degrade painting performance, because the image can no longer be "managed" and kept in VRAM internally.

Testaceous answered 13/3, 2014 at 22:3 Comment(0)
T
5
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedImage bufferedImage = ImageIO.read(new File("norris.jpg"));
        int height = bufferedImage.getHeight(), width = bufferedImage.getWidth();
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int RGBA = bufferedImage.getRGB(x, y);
                int alpha = (RGBA >> 24) & 255;
                int red = (RGBA >> 16) & 255;
                int green = (RGBA >> 8) & 255;
                int blue = RGBA & 255;
            }
        }
    }
}

Assume the buffered image represents an image with 8-bit RGBA color components packed into integer pixels, I search for "RGBA color space" on wikipedia and found following:

In the byte-order scheme, "RGBA" is understood to mean a byte R, followed by a byte G, followed by a byte B, and followed by a byte A. This scheme is commonly used for describing file formats or network protocols, which are both byte-oriented.

With simple Bitwise and Bitshift you can get the value of each color and the alpha value of the pixel.

Very interesting is also the other order scheme of RGBA:

In the word-order scheme, "RGBA" is understood to represent a complete 32-bit word, where R is more significant than G, which is more significant than B, which is more significant than A. This scheme can be used to describe the memory layout on a particular system. Its meaning varies depending on the endianness of the system.

Taegu answered 6/1, 2019 at 15:0 Comment(0)
A
2
byte[] pixels

not

int[] pixels

try this : Java - get pixel array from image

Absorbent answered 13/3, 2014 at 21:38 Comment(3)
will try that. but what does this array containt then? hex-colors? argb-colors?Capful
I prefer getRGB(), it's very useful, try it, getRGB(x,y) returns the color of the pixel in (x ,y) position, if you want I publish a code for thisAbsorbent
I tried this out on a red image, output was following int: -60160 what does this number mean? is it an rgb color?Capful
B
2
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class ImageUtil {

    public static Color[][] loadPixelsFromImage(File file) throws IOException {

        BufferedImage image = ImageIO.read(file);
        Color[][] colors = new Color[image.getWidth()][image.getHeight()];

        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                colors[x][y] = new Color(image.getRGB(x, y));
            }
        }

        return colors;
    }

    public static void main(String[] args) throws IOException {
        Color[][] colors = loadPixelsFromImage(new File("image.png"));
        System.out.println("Color[0][0] = " + colors[0][0]);
    }
}
Brazil answered 28/7, 2016 at 15:4 Comment(0)
S
1

I know this has already been answered, but the answers given are a bit convoluted and could use improvement. The simple idea is to just loop through every (x,y) pixel in the image, and get the color of that pixel.

BufferedImage image = MyImageLoader.getSomeImage();
for ( int x = 0; x < image.getWidth(); x++ ) {
    for( int y = 0; y < image.getHeight(); y++ ) {
        Color pixel = new Color( image.getRGB( x, y ) );
        // Do something with pixel color here :)
    }
}

You could then perhaps wrap this method in a class, and implement Java's Iterable API.

class IterableImage implements Iterable<Color> {

    private BufferedImage image;

    public IterableImage( BufferedImage image ) {
        this.image = image;
    }

    @Override
    public Iterator<Color> iterator() {
        return new Itr();
    }

    private final class Itr implements Iterator<Color> {

        private int x = 0, y = 0;

        @Override
        public boolean hasNext() {
            return x < image.getWidth && y < image.getHeight();
        }

        @Override
        public Color next() {
            x += 1;
            if ( x >= image.getWidth() ) {
                x = 0;
                y += 1;
            }
            return new Color( image.getRGB( x, y ) );
        }

    }

}

The usage of which might look something like the following

BufferedImage image = MyImageLoader.getSomeImage();
for ( Color color : new IterableImage( image ) ) {
    // Do something with color here :)
}
Sagittate answered 31/1, 2019 at 17:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.