# Einzelne Pixel unsichtbar machen



## sebbi1234 (31. März 2007)

Hallo,

ich habe über ein ImageIcon ein Bild in ein JLabel geladen. Da diese Bild kreisförmig ist und über ein anderes Bild fliegen soll, stört selbstverständlich der eckige Rand. Jetzt frage ich mich, ob es möglich ist, festzulegen, dass bestimmte Pixel im JLabel unsichtbar sind, und sich somit dem Hintergrundbild an den betreffenen Stellen anpassen, während das eigentliche Bild dann weiterhin dargestellt wird.

Wenns da ne Möglichkeit gibt würde ich mich über Antworten freuen. Danke!

Gruß


----------



## zeja (1. April 2007)

Hast dus mal mit nem png versucht? Bei png's kann man ja Transparenz benutzen.


----------



## Thomas Darimont (1. April 2007)

Hallo,

schau mal hier:

```
/**
 * 
 */
package de.tutorials;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

/**
 * @author Tom
 */
public class TransparentImageExample extends JFrame {

  Image image;


  public TransparentImageExample() {
    super("TransparentImageExample");
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    try {
      BufferedImage tmp = ImageIO.read(new File("c:/tmp/tom_small.jpg"));
      final ColorRange range = new ColorRange(160, 255, 0, 70, 0, 70);

      ImageFilter transparencyFilter = new RGBImageFilter() {
        public final int filterRGB(int x, int y, int rgb) {
          if (range.contains(rgb | 0xFF000000)) {
            return 0x00FFFFFF & rgb;
          } else {
            return rgb;
          }
        }
      };
      ImageProducer imageProducer = new FilteredImageSource(tmp.getSource(), transparencyFilter);
      image = Toolkit.getDefaultToolkit().createImage(imageProducer);

    } catch (IOException e) {
      e.printStackTrace();
    }

    setSize(400, 300);
    setVisible(true);
  }


  @Override
  public void paint(Graphics g) {
    super.paint(g);
    if (null != image) {
      g.drawImage(image, 50, 50, null);
    }
  }


  /**
   * @param args
   */
  public static void main(String[] args) {
    new TransparentImageExample();
  }

  static class ColorRange {

    int redStart;
    int redEnd;
    int greenStart;
    int greenEnd;
    int blueStart;
    int blueEnd;


    public ColorRange(int redStart, int redEnd, int greenStart, int greenEnd, int blueStart, int blueEnd) {
      this.redStart = redStart;
      this.redEnd = redEnd;
      this.greenStart = greenStart;
      this.greenEnd = greenEnd;
      this.blueStart = blueStart;
      this.blueEnd = blueEnd;
    }


    public boolean contains(int rgb) {
      Color color = new Color(rgb);
      return isInRange(color.getRed(), redStart, redEnd) && isInRange(color.getGreen(), greenStart, greenEnd)
        && isInRange(color.getBlue(), blueStart, blueEnd);
    }


    private boolean isInRange(int value, int start, int end) {
      return value >= start && value <= end;
    }
  }
}
```

Ging IMHO aber auch über eine entsprechende ConvolveOp
http://java.sun.com/javase/6/docs/technotes/guides/2d/spec/j2d-image.html#wp63208

Gruß Tom


----------



## sebbi1234 (1. April 2007)

Danke schon mal für die Antworten.

Thomas, um ganz ehrlich zu sein kapier ich den Quelltext und die Erklärung auf der Seite nicht ganz.

Was ich noch zu meiner Frage hinzufügen sollte ist, dass die Anteile, bei dem Bild, das ich teilweise transparten machen möchte, alle die gleiche Farbe haben. Wie auf dem hier angehängten Bild möchte ich alle Pixel mit dem RGB-Code 238,238,238 durch transparente Pixel ersetzen.

Gibt es da keine einfachere Methode?

Gruß
Sebastian


----------



## Thomas Darimont (1. April 2007)

Hallo,

schau mal hier:

```
/**
 * 
 */
package de.tutorials;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

/**
 * @author Tom
 */
public class TransparentImageExample extends JFrame {

  Image image;


  public TransparentImageExample() {
    super("TransparentImageExample");
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    try {
      BufferedImage tmp = ImageIO.read(new File("c:/tmp/eurofighter.jpg"));
      Color color = new Color(238, 238, 238);
      final int referenceRgb = color.getRGB();
      ImageFilter transparencyFilter = new RGBImageFilter() {
        public final int filterRGB(int x, int y, int rgb) {
          if (referenceRgb == (rgb | 0xFF000000)) {
            return 0x00FFFFFF & rgb;
          } else {
            return rgb;
          }
        }
      };
      ImageProducer imageProducer = new FilteredImageSource(tmp.getSource(), transparencyFilter);
      image = Toolkit.getDefaultToolkit().createImage(imageProducer);

    } catch (IOException e) {
      e.printStackTrace();
    }

    setSize(400, 300);
    setVisible(true);
  }


  @Override
  public void paint(Graphics g) {
    super.paint(g);
    g.setColor(Color.ORANGE);
    g.fillRect(0, 0, getWidth(), getHeight());
    if (null != image) {
      g.drawImage(image, 50, 50, null);
    }
  }


  /**
   * @param args
   */
  public static void main(String[] args) {
    new TransparentImageExample();
  }
}
```

Nur diese eine Farbe zu ersetzen reicht leider nicht, da sich die RGB Werte vor allen an den Objekträndern ein wenig "verzerren". Hier kannst du aber dann mit der oben gezeigten ColorRange arbeiten.

Gruß Tom


----------



## zeja (1. April 2007)

Oder direkt ein png benutzen. Kommt aufs gleiche raus:


```
/**
 * 
 */
package de.tutorials;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
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.SwingConstants;

public class Transparency {

	public static void main(String[] args) {
		JFrame window = new JFrame("Transparency");
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.setLayout(new FlowLayout( ));

		JLabel jpgLabel = new JLabel("jpg", new ImageIcon("eurofighter.jpg"),
				SwingConstants.CENTER);
		jpgLabel.setBackground(Color.RED);
		jpgLabel.setOpaque(true);
		window.getContentPane( ).add(jpgLabel);

		JLabel pngLabel = new JLabel("png", new ImageIcon("eurofighter.png"),
				SwingConstants.CENTER);
		pngLabel.setBackground(Color.RED);
		pngLabel.setOpaque(true);
		window.getContentPane( ).add(pngLabel);

		BufferedImage tmp;
		try {
			tmp = ImageIO.read(new File("eurofighter.jpg"));
			final ColorRange range = new ColorRange(238, 238, 238, 238, 238,
					238);

			ImageFilter transparencyFilter = new RGBImageFilter( ) {

				public final int filterRGB(int x, int y, int rgb) {
					if (range.contains(rgb | 0xFF000000)) {
						return 0x00FFFFFF & rgb;
					}
					else {
						return rgb;
					}
				}
			};
			ImageProducer imageProducer = new FilteredImageSource(tmp
					.getSource( ), transparencyFilter);
			Image filtered = Toolkit.getDefaultToolkit( ).createImage(
					imageProducer);

			JLabel filteredLabel = new JLabel("filtered", new ImageIcon(
					filtered), SwingConstants.CENTER);
			filteredLabel.setBackground(Color.RED);
			filteredLabel.setOpaque(true);
			window.getContentPane( ).add(filteredLabel);
		}
		catch (IOException e) {
			e.printStackTrace( );
		}

		window.setSize(300, 300);
		window.pack( );
		window.setVisible(true);
	}

	static class ColorRange {

		int redStart;
		int redEnd;
		int greenStart;
		int greenEnd;
		int blueStart;
		int blueEnd;

		public ColorRange(int redStart, int redEnd, int greenStart,
				int greenEnd, int blueStart, int blueEnd) {
			this.redStart = redStart;
			this.redEnd = redEnd;
			this.greenStart = greenStart;
			this.greenEnd = greenEnd;
			this.blueStart = blueStart;
			this.blueEnd = blueEnd;
		}

		public boolean contains(int rgb) {
			Color color = new Color(rgb);
			return isInRange(color.getRed( ), redStart, redEnd)
					&& isInRange(color.getGreen( ), greenStart, greenEnd)
					&& isInRange(color.getBlue( ), blueStart, blueEnd);
		}

		private boolean isInRange(int value, int start, int end) {
			return value >= start && value <= end;
		}
	}
}
```


----------



## sebbi1234 (2. April 2007)

Vielen Dank für eure Antworten. Ich hab das jetzt soweit in mein Programm eingefügt, dass ich den Hintergrund des Flugzeugs also in alle Farben umwandeln kann. Wie schaffe ich es jetzt aber diesen Bereich, den ich über setBackground(Color.Green) z.B. grün machen kann nun transparent zu bekommen. Ich nehm mal an dafür muss ich Color.Translucent verwenden, oder? Wenn ich jedoch 
filteredLabel.setBackground(Color.Translucent); 
benutze funktioniert das jedoch nicht. Da man ja den Transparenzwert noch angeben muss kann es ja auch nicht funktionieren. Wie aber gibt man es dann korrekt an, so dass der Bereich vollkommen transparent wird?

Viele Grüße
Sebastian


----------

