Getting pixel data from an image using java

72,452

Solution 1

This:

for(int i = 0; i < img.getHeight(); i++){
    for(int j = 0; j < img.getWidth(); j++){
        rgb = getPixelData(img, i, j);

Does not match up with this:

private static int[] getPixelData(BufferedImage img, int x, int y) {

You have i counting the rows and j the columns, i.e. i contains y values and j contains x values. That's backwards.

Solution 2

I was looking for this same ability. Didn't want to enumerate the entire image, so I did some searching and used PixelGrabber.

Image img = Toolkit.getDefaultToolkit().createImage(filename);
PixelGrabber pg = new PixelGrabber(img, 0, 0, -1, -1, false);
pg.grabPixels(); // Throws InterruptedException
width = pg.getWidth();
height = pg.getHeight();
int[] pixels = (int[])pg.getPixels();

You could use the int[] directly here, pixels are in a format dictated by the ColorModel from pg.getColorModel(), or you can change that false to true and force it to be RGB8-in-ints.

I've since discovered that the Raster and Image classes can do this too, and there have been some useful classes added in javax.imageio.*.

BufferedImage img = ImageIO.read(new File(filename)); // Throws IOException
int[] pixels = img.getRGB(0,0, img.getWidth(), img.getHeight, null, 0, img.getWidth());
// also available through the BufferedImage's Raster, in multiple formats.
Raster r = img.getData();
int[] pixels = r.getPixels(0,0,r.getWidth(), r.getHeight(), (int[])null);

There are several getPixels(...) methods in Raster as well.

Solution 3

This works too:

BufferedImage img = ImageIO.read(file);
int[] pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();

Solution 4

int argb = img.getRGB(x, y); Your code

int argb = img.getRGB(y, x); my changes now it works

Solution 5

You have to change:

for(int i = 0; i < img.getHeight(); i++){
    for(int j = 0; j < img.getWidth(); j++){
        rgb = getPixelData(img, i, j);

Into

for(int i = 0; i < img.getWidth(); i++){
    for(int j = 0; j < img.getHeight(); j++){
        rgb = getPixelData(img, i, j);

Because the second parameter from getPixelData is the x-value and the thirth is the y-value. You switched the parameters.

Share:
72,452
Matt
Author by

Matt

Updated on July 09, 2020

Comments

  • Matt
    Matt over 3 years

    I'm trying to get the pixel rgb values from a 64 x 48 bit image. I get some values but nowhere near the 3072 (= 64 x 48) values that I'm expecting. I also get:

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
    at sun.awt.image.ByteInterleavedRaster.getDataElements(ByteInterleavedRaster.java:301)
    at java.awt.image.BufferedImage.getRGB(BufferedImage.java:871)
    at imagetesting.Main.getPixelData(Main.java:45)
    at imagetesting.Main.main(Main.java:27)
    

    I can't find the out of bounds error...

    Here's the code:

    package imagetesting;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import java.io.File;
    import java.awt.image.BufferedImage;
    public class Main {
    public static final String IMG = "matty.jpg";
    public static void main(String[] args) {
        BufferedImage img;
        try {
            img = ImageIO.read(new File(IMG));
            int[][] pixelData = new int[img.getHeight() * img.getWidth()][3];
            int[] rgb;
            int counter = 0;
            for(int i = 0; i < img.getHeight(); i++){
                for(int j = 0; j < img.getWidth(); j++){
                    rgb = getPixelData(img, i, j);
                    for(int k = 0; k < rgb.length; k++){
                        pixelData[counter][k] = rgb[k];
                    }
                    counter++;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static int[] getPixelData(BufferedImage img, int x, int y) {
    int argb = img.getRGB(x, y);
    int rgb[] = new int[] {
        (argb >> 16) & 0xff, //red
        (argb >>  8) & 0xff, //green
        (argb      ) & 0xff  //blue
    };
    System.out.println("rgb: " + rgb[0] + " " + rgb[1] + " " + rgb[2]);
    return rgb;
    }
    }