webentwicklung-frage-antwort-db.com.de

Rufen Sie mit BufferedImages die Farbe jedes Pixels eines Bildes ab

Ich versuche, jede einzelne Farbe eines jeden Pixels eines Bildes zu erhalten ... Meine Idee war folgende:

int[] pixels;
BufferedImage image;

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

Ist das richtig? Ich kann nicht einmal überprüfen, was das "Pixel" -Array enthält, da folgende Fehlermeldung angezeigt wird:

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

Ich möchte nur die Farbe jedes Pixels in einem Array erhalten. Wie kann ich das erreichen?

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

natürlich müssen Sie eine for-Schleife für alle Pixel hinzufügen

23
Black Shadow

Das Problem (auch bei der Antwort, die von der ersten Antwort verlinkt wurde) ist, dass Sie kaum wissen, welchen Typ Ihr ​​gepuffertes Bild nach dem Lesen mit ImageIO genau haben wird. Es kann eine DataBufferByte oder eine DataBufferInt enthalten. Sie können es in einigen Fällen über BufferedImage#getType() ableiten, im schlimmsten Fall hat es den Typ TYPE_CUSTOM, und Sie können nur auf einige instanceof-Tests zurückgreifen.

Sie können jedoch Ihr Bild in ein BufferedImage konvertieren, das garantiert eine DataBufferInt mit ARGB-Werten hat - und zwar mit etwas Ähnlichem

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

Andernfalls können Sie image.getRGB(x,y) aufrufen, wodurch die erforderlichen Konvertierungen im laufenden Betrieb durchgeführt werden können.

Übrigens: Beachten Sie, dass der Erhalt des Datenpuffers eines BufferedImage die Malperformance beeinträchtigen kann, da das Bild nicht mehr "verwaltet" und intern in VRAM aufbewahrt werden kann.

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

nicht

int[] pixels

probieren Sie folgendes aus: Java - Pixel-Array von Bild erhalten

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

Angenommen, das gepufferte Bild stellt ein Bild mit 8-Bit-RGBA-Farbkomponenten dar, die in ganzzahlige Pixel gepackt sind. Ich suche auf Wikipedia nach "RGBA-Farbraum" und habe folgendes gefunden:

Im Byte-Reihenfolge-Schema wird unter "RGBA" ein Byte R, .__ verstanden. gefolgt von einem Byte G, gefolgt von einem Byte B, gefolgt von einem Byte A . Dieses Schema wird häufig zur Beschreibung von Dateiformaten oder Netzwerk verwendet Protokolle, die beide Byte-orientiert sind.

Mit Simple Bitwise und Bitshift können Sie den Wert jeder Farbe und den Alpha-Wert des Pixels ermitteln.

Sehr interessant ist auch das andere Ordnungsschema von RGBA:

Unter dem Wort-Reihenfolge-Schema versteht man unter "RGBA" ein vollständiges 32-Bit-Wort, wobei R wichtiger ist als G, was mehr .__ ist. signifikanter als B, der signifikanter als A. Dieses Schema kann verwendet werden, um das Speicherlayout auf einem bestimmten System zu beschreiben. Es ist Die Bedeutung variiert je nach Endianness des Systems.

0
Long Nguyen

Ich weiß, dass dies bereits beantwortet wurde, aber die Antworten sind ein wenig kompliziert und könnten eine Verbesserung verwenden. Die einfache Idee ist, einfach jedes (x, y) Pixel im Bild zu durchlaufen und die Farbe dieses Pixels zu erhalten .

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

Sie könnten diese Methode dann vielleicht in eine Klasse einschließen und Javas Iterable API implementieren.

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

    }

}

Die Verwendung davon könnte in etwa wie folgt aussehen

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