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?
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
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.
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]);
}
}
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.
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 :)
}