Wie kann man auf die einzelnen Pixel eines Bildes zugreifen und diese manipulieren?
Die Methode processImage()
liest zunächst
über die statische Methode ImageIO.read(File file)
ein Bild als BufferedImage
über dessen
File-Objekt ein. Das zugehörige ColorModel
und
Raster
werden ermittelt. Die Klasse ColorModel
kapselt Methoden zur Konvertierung der Pixelwerte in Farb- und
Transparenzkomponenten und deren Bearbeitung. Ein Raster
repräsentiert ein Array, das die Pixelwerte eines
definierten rechteckigen Bereiches beschreibt.
In einer
geschachtelten Schleife werden die einzelnen Pixel mittels getDataElements()
ausgelesen und deren RGB-Wert als int
über das
Model ermittelt. Hiermit kann nun ein Color-Objekt erstellt
werden, dessen einzelne Farb-Komponenten ausgelesen und beliebig
manipuliert werden können. Im Beispiel wird jeder Farbwert
dann um 50 erhöht, wenn nach Addieren von limit
der Grenzwert von 255 nicht überschritten wird. Da sich
hierdurch die Anzahl rein weißer Pixel erhöht, kommt
es zur Bildung weißer Flächen im Bild.
Der Rest
der Methode kehrt den Prozess des Auslesens um: ein neues
Color-Objekt wird gebildet, ein entsprechender int-Wert
erstellt, der ins ColorModel
eingelesen und auf's Raster
gesetzt wird.
package grafik.bildbearbeitung;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class ManipulateImage {
private static final long serialVersionUID = 1L;
JPanel panel;
JLabel label;
ImageIcon icon;
BufferedImage image;
public ManipulateImage() {
//processImage();
makeImage();
icon = new ImageIcon(image);
label = new JLabel(icon);
label.setBorder(new LineBorder(Color.WHITE));
panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBackground(Color.DARK_GRAY);
panel.add(label, BorderLayout.CENTER);
JFrame frame = new JFrame("Pixel manipulieren");
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private void processImage(){
File file = new File("test.jpg");
try {
this.image = ImageIO.read(file);
} catch (IOException ex) {
ex.printStackTrace();
}
ColorModel model = image.getColorModel();
WritableRaster raster = image.getRaster();
for(int i=0; i<image.getWidth(); i++){
for(int j=0; j<image.getHeight(); j++){
Object dataAlt = raster.getDataElements(i, j, null);
int argbAlt = model.getRGB(dataAlt);
Color c = new Color(argbAlt, true);
int limit = 150, wert = 50;
int r = (c.getRed() + limit) < 256 ? c.getRed() + wert : 255;
int g = (c.getGreen() + limit) < 256 ? c.getGreen() + wert : 255;
int b = (c.getBlue() + limit) < 256 ? c.getBlue() + wert : 255;
Color cNeu = new Color(r, g, b);
int argbNeu = cNeu.getRGB();
Object dataNeu = model.getDataElements(argbNeu, null);
raster.setDataElements(i, j, dataNeu);
}
}
}
private void makeImage(){
int width = 200, height = 200;
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
WritableRaster raster = image.getRaster();
ColorModel model = image.getColorModel();
Color c1 = Color.RED;
int argb1 = c1.getRGB();
Object data1 = model.getDataElements(argb1, null);
Color c2 = Color.GRAY;
int argb2 = c2.getRGB();
Object data2 = model.getDataElements(argb2, null);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
raster.setDataElements(i, j, data1);
if(i>50 && i<150 && j>50 && j<150){
raster.setDataElements(i, j, data2);
}
}
}
}
public static void main(String args[]) {
SwingUtilities.invokeLater(() -> new ManipulateImage());
}
}
Das Verfahren von makeImage()
ist prinzipiell
gleich. Es wird jedoch ein leeres, beliebig grosses (hier 200 x
200 px) BufferedImage-Objekt erstellt, Raster
und ColorModel
werden ermittelt und zwei Color-Objekte gebildet. Nach Wandel
und Auslesen der Data-Arrays mittels getDataElements()
werden die Pixelwerte in einer geschachtelten Schleife dem Raster
übergeben.
Das Ergebnis sieht wie folgt aus.
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.