Ich habe von einer anderen Java-Applikation ein BufferedImage erhalten. Dieses Bild hatte einen weißen Hintergrund, den ich gerne transparent haben wollte.

Einen weißen Hintergrund transparent zu machen klingt zuerst recht simpel. Mit Bildbearbeitungsprogrammen wie GIMP ist es auch eine relativ triviale Operation: Dem Bild einen Alphakanel hinzufügen, entsprechende Flächen markieren und entfernen und das Bild in einem Transparenz unterstützenden Format abspeichern, wie PNG.

Wie macht man das allerdings programmiertechnisch? Denn vor allem bei dynamisch generierten Bildern ist es so gut wie unmöglich zu sagen, welcher Bereich eines Bilder transparent sein soll. Aber ich möchte im Prinzip keinen Bereich transparent machen, sondern eine bestimmte Farbe: Das Weiß des Hintergrundes. Aber wie geht man dabei mit der Klasse BufferedImage vor? Leider bietet sie keine Methode an, wie "mache Farbe X transparent".

Also müssen wir wohl das Bild Pixel für Pixel durchgehen und bei Übereinstimmung den Farbwert des Bildes ändern.

Nach einer relativ kurzen Recherche bin ich auf eine entsprechende Frage bei stackoverflow gestoßen, die auch eine schöne Lösung beeinhaltete, aus der ich mir eine simple Methode gestrickt habe.

public static final BufferedImage makeTransparent(final BufferedImage image, final Color color) {
    final ImageFilter filter = new RGBImageFilter() {
        private static final int ALPHA = 0xFF000000;
        private final int markerRGB = color.getRGB() | ALPHA;

        @Override
        public int filterRGB(final int x, final int y, final int rgb) {
            if ((rgb | ALPHA) == markerRGB) {
                // Mark the alpha bits as zero - transparent
                return 0x00FFFFFF & rgb;
            } else {
                // nothing to do
                return rgb;
            }
        }
    };

    final ImageProducer ip = new FilteredImageSource(image.getSource(), filter);
    final Image img = Toolkit.getDefaultToolkit().createImage(ip);
    final BufferedImage b = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    final Graphics2D g2 = b.createGraphics();
    g2.drawImage(img, 0, 0, null);
    g2.dispose();
    return b;
}

Der erste und wichtigste Teil der Methode nutzt einen RGBImageFilter, um durch alle Pixel des Bildes zu iterieren und diese bei Übereinstimmung mit der übergebenen Farbe auf transparent zu setzen. Der zweite Teil erzeugt mit Hilfe des implementierten ImageFilters ein Image, welches für die Konstruktion eines neuen BufferedImage inkl. Alphakanal verwendet wird.

blogroll
tags