web-dev-qa-db-fra.com

Obtenir la couleur de chaque pixel d'une image en utilisant BufferedImage

J'essaie d'obtenir chaque couleur de chaque pixel d'une image ..__ Mon idée était la suivante:

int[] pixels;
BufferedImage image;

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

Est-ce correct? Je ne peux même pas vérifier ce que contient le tableau "pixels", car j'obtiens l'erreur suivante:

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

Je voudrais juste recevoir la couleur de chaque pixel d'un tableau, comment puis-je y parvenir?

12
user2410644
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);
  }
}

bien sûr, vous devez ajouter une boucle for pour tous les pixels

23
Black Shadow

Le problème (également avec la réponse qui était liée à la première réponse) est que vous ne savez presque jamais quel type exact sera l'image tamponnée après l'avoir lue avec ImageIO. Il pourrait contenir une DataBufferByte ou une DataBufferInt. Vous pouvez le déduire dans certains cas via BufferedImage#getType(), mais dans le pire des cas, il est de type TYPE_CUSTOM et vous ne pouvez alors que vous replier à certains tests instanceof.

Cependant, vous pouvez convertir votre image en une image BufferedImage dont la valeur DataBufferInt avec ARGB est garantie - à savoir avec quelque chose comme:

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;
}

Sinon, vous pouvez appeler image.getRGB(x,y) pour effectuer les conversions requises à la volée.

BTW: Notez que l'obtention du tampon de données d'une BufferedImage peut dégrader les performances de la peinture, car l'image ne peut plus être "gérée" et conservée dans la VRAM en interne.

6
Marco13
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]);
    }
}
2
Daniel
byte[] pixels

ne pas

int[] pixels

essayez ceci: Java - Obtenir un tableau de pixels à partir d’image

2
Black Shadow
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;
            }
        }
    }
}

Supposons que l'image mise en mémoire tampon représente une image avec des composants de couleur RGBA 8 bits intégrés dans des pixels entiers, je recherche "espace de couleur RGBA" sur wikipedia et trouve ce qui suit:

Dans le schéma d'ordre d'octet, "RGBA" signifie un octet R, suivi d'un octet G, suivi d'un octet B et d'un octet A . Ce schéma est couramment utilisé pour décrire les formats de fichiers ou le réseau protocoles, qui sont tous deux orientés octet.

Avec Bitwise et Bitshift simples, vous pouvez obtenir la valeur de chaque couleur et la valeur alpha du pixel.

L’autre schéma d’ordre de RGBA est également très intéressant:

Dans le schéma d'ordre des mots, "RGBA" est censé représenter un .__ complet. Mot 32 bits, où R est plus significatif que G, ce qui est plus significatif que B, qui est plus important que A. Ce schéma peut être utilisé pour décrire la disposition de la mémoire sur un système particulier. Ses le sens varie en fonction de l’endianité du système.

0
Long Nguyen

Je sais que cela a déjà été répondu, mais les réponses fournies sont un peu compliquées et pourraient améliorer ... .. L'idée est simplement de parcourir en boucle chaque pixel (x, y) de l'image et d'obtenir la couleur de ce 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 :)
    }
}

Vous pourriez alors peut-être envelopper cette méthode dans une classe et implémenter l'API Iterable de Java.

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 ) );
        }

    }

}

L'utilisation de ce qui pourrait ressembler à quelque chose comme ce qui suit

BufferedImage image = MyImageLoader.getSomeImage();
for ( Color color : new IterableImage( image ) ) {
    // Do something with color here :)
}
0
Robert E Fry