Transparentes BufferedImage über BufferedImage

Status
Nicht offen für weitere Antworten.
F

fat32

Gast
Hi,

wie kann ich ein transparentes BufferedImage auf ein "normales" (RGB) BufferedImage zeichnen, so dass das darunterliegende Bild an den Transparenten Stellen des transparenten BIs durchscheint?

Ich habe da gerade keinen guten Ansatz... SO sieht es aus:

Java:
protected void paintComponent( Graphics g )
  {
	 BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
	 ((Graphics2D)img.getGraphics()).setBackground(new Color(0,0,0,0));
	 ((Graphics2D)img.getGraphics()).clearRect(0, 0, 100, 100);
	 ((Graphics2D)img.getGraphics()).setColor(new Color(0,0,0,200));
	 ((Graphics2D)img.getGraphics()).fillOval(10, 10, 10, 10);
	 
    if (this.image != null)
    {
      ((Graphics2D)g).drawImage(this.image, 0, 0, null);
      ((Graphics2D)g).drawImage(img, 0, 0, null);
    }
  }

Das Resultat ist sehr bescheiden...
Ich muss zugeben, dass ich beim Googeln nichts gefunden habe, was auf mein Problem gepasst hätte...

MfG
Simon
 

Marco13

Top Contributor
Wenn man den ursprünglichen Thread http://www.java-forum.org/softwareentwicklung/92303-verschiedene-zeichenwerkzeuge.html#post585155 nicht kennt, könnte man geneigt sein, hier unpassende Tipps zu geben. Vielleicht könntest du die Dinge, die du während des Erstellens schon zeichnen willst (wie z.B. ein Kreis, der größer gezogen wird) als eigene Objekte zeichnen - im Pseudocode sowas wie
Java:
interface Paintable { void paintOn(Graphics g); }
class Kreis implements Paintable { ... malt den Kreis ... }

class Malfenster
{
    private Paintable currentObject;
    private BufferedImage finalImage;

    void paintComponent(Graphics g)
    {
        g.drawImage(finalImage); // Male das schon vorhandene Bild
        if (currentObject != null) currentObject.paintOn(g); // und ggf. das Objekt, was gerade erstellt wird
    }


    void mousePressed()
    {
        currentObject = new Kreis();
    }
    void mouseDragged()
    {
        verändereGrößeVonKreis();
        repaint();
    }

    void mouseReleased()
    {
        // Aktuell gemaltes "ding" ins Bild übertragen:
        currentObject.paintOn(finalImage.getGraphics());
        currentObject = null;
        repaint();
    }
}


EDIT: Noch allgemein: In der paintComponent ein neues Bild erstellen ist schlecht. WENN du das mit transparenten Bildern lösen wolltest, dann könntest du vielleicht irgendwie EIN mal so ein durchsichtiges Bild erstellen, und das immer wieder verwenden...
 
Zuletzt bearbeitet:

Guybrush Threepwood

Top Contributor
Die bescheidene Qualität könnte an den Quality-Hints liegen. Versuche es mal so:

Java:
protected void paintComponent( Graphics g )
  {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g2.setRenderingHint(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
     BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
     ((Graphics2D)img.getGraphics()).setBackground(new Color(0,0,0,0));
     ((Graphics2D)img.getGraphics()).clearRect(0, 0, 100, 100);
     ((Graphics2D)img.getGraphics()).setColor(new Color(0,0,0,200));
     ((Graphics2D)img.getGraphics()).fillOval(10, 10, 10, 10);
     
    if (this.image != null)
    {
      g2.drawImage(this.image, 0, 0, null);
      g2.drawImage(img, 0, 0, null);
    }
  }

Ich habe schon öfters halbtransparente Images übereinander gelegt (eingelesen aus externen Bilddateien mit Alpha-Kanal) und das hat immer super geklappt. Davon abgesehen hat Marco13 völlig recht: Das transparente BufferedImage sollte am Besten außerhalb von paintComponent erzeugt werden, da das sonst relativ viel Rechenleistung kosten kann.
 
F

fat32

Gast
Vielen Dank für den Code!

Hast du den Code schonmal so erfolgreich verwendet?
Bei mir wird zwar ein 100x100-großes schwartes Feld aufs eigentliche Bild gelegt, aber das Ding ist nicht wirklich transparent... Das, was drunter ist, wird verdeckt.

@Macro13:
Ja, das wird später noch so gemacht, dass es nur einmal angelegt wird.
Das ist jetzt nur zu Testzwecken so.
 

Marco13

Top Contributor
Also... abgesehen davon, dass es unschön ist, GLAUBE ich mich zu erinnern, dass dieses mehrfache "getGraphics" daran schuld sein kann. (Wir wissen ja: getGraphics ist böse ;) auf BufferedImages eigentlich nicht, aber manchmal dann doch)

Das sollte man ggf. eher so schreiben
Java:
Graphics2D g = img.createGraphics();
g.setBackground(new Color(0,0,0,0));
g.clearRect(0, 0, 100, 100);
g.setColor(new Color(0,0,0,200));
g.fillOval(10, 10, 10, 10);
g.dispose();
 
S

Spacerat

Gast
Wohl auch bei BufferedImage böse, wie der Methodenname schon andeutet...[JAVA=1114]// aus java.awt.image.BufferedImage.class

/**
* This method returns a {@link Graphics2D}, but is here
* for backwards compatibility. {@link #createGraphics() createGraphics} is more
* convenient, since it is declared to return a
* <code>Graphics2D</code>.
* @return a <code>Graphics2D</code>, which can be used to draw into
* this image.
*/
public java.awt.Graphics getGraphics() {
return createGraphics();
}[/code]Es wird offenbar stets ein neuer GraphicsContext erstellt, in welchen das aktuelle Raster kopiert wird. Auch daran zu erkennen, dass die Kontexte zweier aufeinander folgenden [c]getGraphics()[/c] niemals identisch (==) sind.
 

Guybrush Threepwood

Top Contributor
Habe gerade mal in meinem Code gestöbert und bin auf die Zeile gestoßen:
Java:
g2.setComposite(AlphaComposite.getInstance(
					AlphaComposite.SRC_OVER, 0.55f));
Alles was danach gezeichnet wird sollte transparent erscheinen.

Noch ein Tipp: Du solltest in paintComponent keine neuen Objekte (new Color(...) etc.) anlegen. Das kann unter Umständen zu Endlosschleifen führen, da das Instanzieren wieder zu einem Neuaufruf der paintComponent-Methode führen kann. Das war bei mir bereits einmal der Fall und es hat lange gedauert, bis ich den Fehler gefunden habe.

P.S.: Ich habe Deinen Code ehrlich gesagt nicht getestet. War mir zu mühsam, den ganzen Rest außenrum zu schreiben.
 
F

fat32

Gast
Ok, daran lags! (createGraphics) Vielen vielen Dank

Ich erzeuge das Bild jetzt einmalig so:

Java:
public void createPreviewImage()
  {
	  this.previewImage = new BufferedImage(this.image.getWidth(), this.image.getHeight(), BufferedImage.TYPE_INT_ARGB);
	  Graphics2D g2d = this.previewImage.createGraphics();
	  g2d.setBackground(new Color(255,255,255,0));
	  g2d.clearRect(0, 0, 100, 100);
	  g2d.setColor(new Color(0,0,0,255));
  }

Klappt hervorragend.

Allerdings stört es mich, dass ich zum Löschen des Bildes immer so viel schreiben muss:
Java:
Graphics2D g = preview.createGraphics();
		g.setBackground(new Color(255,255,255,0));
		g.clearRect(0, 0, this.preview.getWidth(), this.preview.getHeight());

Da ich das sehr oft benötige, dachte ich mir, dass ich eine eigene Klasse MyBufferedImage erstelle und von BufferedImage erbe.
Allerdings hat BufferedImage ja viele Konstruktoren. Muss ich die dann alle "überladen" oder reicht mir ein Konstruktor?
Weiß ja nicht, wie BI intern so arbeitet.

MfG
Simon
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Nix überschreiben oder erben...
Java:
private static void clearImage(BufferedImage image)
{
    Graphics2D g = image.createGraphics();
    g.setBackground(new Color(255,255,255,0));
    g.clearRect(0, 0, image.getWidth(), image.getHeight());
    g.dispose(); // Nicht vergessen...
}

Aufruf dann einfach überall mit
[c]clearImage(this.preview);[/c]
 
F

fat32

Gast
So kann man es natürlich auch machen.
Die Frage ist nur, ob das in OOP-Hinsicht sauber gelöst ist.
 

Marco13

Top Contributor
Hier mal ein ganz selbsbewußtes: JA :)
Das ist eine private Methode, die niemand sieht, und die einfach etwas macht, was man häufiger an verschiednen Stelle mal machen muss. (BTW: schau dir nochmal die doku zu "clearRect" an!)
Die "Funktion, gecleart werden zu können" ist nichts, was man durch Vererbung oder ähnliches irgendwo hinzufügen müßte. Du erstellst keine Spezielle ART von Bild (also nicht ein Bild einer Klasse, die von BufferedImage erben müßte), sondern du machst "von außen" etwas, was man mit jedem BufferedImage machen kann.
Aber es stimmt schon - manchmal ist es nicht so leicht: http://www.java-forum.org/allgemein...embermethoden-statische-utility-methoden.html ;)
 
F

fat32

Gast
Interressant!
Man lernt immer wieder dazu :)

Habs jetzt mit der statischen Methode gelöst.
 

Ebenius

Top Contributor
[thread=86306]Wie kann ich ein Thema als [Erledigt] markieren?[/thread]
Hab ich mal gemacht.

Ebenius
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
stroggi Swing Mehrere transparentes Objekte (Grafiken) über einem Bild (JLabel) darstellen AWT, Swing, JavaFX & SWT 4
windl Transparentes / halbtransparentes Fenster AWT, Swing, JavaFX & SWT 1
D Transparentes Hauptfenster Events AWT, Swing, JavaFX & SWT 1
S 2D-Grafik Transparentes JScrollPane AWT, Swing, JavaFX & SWT 0
X Transparentes Overlay AWT, Swing, JavaFX & SWT 3
S Canvas durch transparentes JPanel sichtbar machen AWT, Swing, JavaFX & SWT 2
B Swing Transparentes JPanel, Schrift verschmiert AWT, Swing, JavaFX & SWT 22
S Fix für transparentes Systemtray? AWT, Swing, JavaFX & SWT 6
D Transparentes JFrame mit inhalt AWT, Swing, JavaFX & SWT 7
G SWT Linie unter transparentes Canvas zeichnen AWT, Swing, JavaFX & SWT 4
0 Transparentes Panel ohne Rahmen AWT, Swing, JavaFX & SWT 5
Kr0e Transparentes Image -> getGraphics AWT, Swing, JavaFX & SWT 8
S Transparentes JPanel auf einem JimiCanvas AWT, Swing, JavaFX & SWT 2
G transparentes Fenster + Speicherverbrauch AWT, Swing, JavaFX & SWT 3
K Popup Deluxe (Transparentes Popup)! AWT, Swing, JavaFX & SWT 8
P Transparentes Window/JFrame (mit SkinLF?) AWT, Swing, JavaFX & SWT 10
M Transparentes gif als extra Klasse auf einen JFrame zeichen AWT, Swing, JavaFX & SWT 17
I Arbeitsspeicherverbrauch BufferedImage.TYPE_INT_RGB vs. TYPE_3BYTE_BGR AWT, Swing, JavaFX & SWT 6
H BufferedImage zurücksetzen funktioniert nicht AWT, Swing, JavaFX & SWT 12
L AWT Ändern der Farbe eines BufferedImage mit Farbähnlichkeit AWT, Swing, JavaFX & SWT 5
I GEmaltes BufferedImage löschen AWT, Swing, JavaFX & SWT 3
cool_brivk24 BufferedImage einem ClickEvent hinzufügen AWT, Swing, JavaFX & SWT 13
cool_brivk24 AWT BufferedImage wird nicht geladen AWT, Swing, JavaFX & SWT 17
J linken Bildausschnitt eines BufferedImage abschneiden AWT, Swing, JavaFX & SWT 4
Zar von Domarus JFrame zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 3
S 2D-Grafik User-BufferedImage rotieren im Zentrum und ohne "anpassung" AWT, Swing, JavaFX & SWT 2
C Pixel-Rendering/Animation Performance in BufferedImage AWT, Swing, JavaFX & SWT 1
H Swing BufferedImage zeichnen AWT, Swing, JavaFX & SWT 1
C Swing BufferedImage zeichnen und JLabels setzen. AWT, Swing, JavaFX & SWT 17
G Subimage von BufferedImage speichern AWT, Swing, JavaFX & SWT 4
D JPanel Graphic2D als BufferedImage Speichern AWT, Swing, JavaFX & SWT 5
D BufferedImage -> Feature Extraktion. Unterschiedliche BufferedImage imageTypes problem AWT, Swing, JavaFX & SWT 4
I 2D-Grafik Shape aus BufferedImage "löschen" AWT, Swing, JavaFX & SWT 2
M 2D-Grafik LookupOp Operation auf BufferedImage AWT, Swing, JavaFX & SWT 7
GianaSisters 2D-Grafik BufferedImage.getSubimage - Frage AWT, Swing, JavaFX & SWT 7
P BufferedImage schlechte Qualität beim Abspeichern AWT, Swing, JavaFX & SWT 9
S BufferedImage als schwarz-weiß-Bild AWT, Swing, JavaFX & SWT 3
Luk10 BufferedImage[...].getData() vs BufferedImage.setRGB() AWT, Swing, JavaFX & SWT 2
D Schnelles kopieren von Pixeln in ein BufferedImage AWT, Swing, JavaFX & SWT 25
J Flackern wie mit BufferedImage beheben AWT, Swing, JavaFX & SWT 4
N Swing BufferedImage neu laden AWT, Swing, JavaFX & SWT 10
N 2D-Grafik BufferedImage, Line2D, Swing und die Probleme AWT, Swing, JavaFX & SWT 5
Luk10 BufferedImage auf ein anderes BufferedImage zeichnen AWT, Swing, JavaFX & SWT 6
P BufferedImage auf JPanel AWT, Swing, JavaFX & SWT 11
K 2D-Grafik BufferedImage eingelesen, welches Modell?! AWT, Swing, JavaFX & SWT 2
T BufferedImage bei paintComponent AWT, Swing, JavaFX & SWT 6
C 2D-Grafik BufferedImage laden, Frage zum Code AWT, Swing, JavaFX & SWT 2
0x7F800000 2D-Grafik int[] zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 27
H 2D-Grafik BufferedImage aus Integer-Array AWT, Swing, JavaFX & SWT 3
Luk10 2D-Grafik BufferedImage sauber rotieren AWT, Swing, JavaFX & SWT 16
P Image mehrfach in ein BufferedImage zeichnen AWT, Swing, JavaFX & SWT 7
A BufferedImage nach dem Speichern immer schwarz AWT, Swing, JavaFX & SWT 8
J Bild aus Datei in BufferedImage laden AWT, Swing, JavaFX & SWT 4
E BufferedImage Alphaknal ein- und ausblenden AWT, Swing, JavaFX & SWT 7
N BufferedImage zeichnen AWT, Swing, JavaFX & SWT 4
D BufferedImage Größe skalieren AWT, Swing, JavaFX & SWT 2
P Swing Vom BufferedImage bei paintComponent nur soviel zeichnen, wie nötig AWT, Swing, JavaFX & SWT 3
B 2D-Grafik BufferedImage Performance AWT, Swing, JavaFX & SWT 3
Y frage zu BufferedImage AWT, Swing, JavaFX & SWT 7
E AWT RenderedImage aus BufferedImage erzeugen, um Bild abzuspeichern? AWT, Swing, JavaFX & SWT 4
S Unterscheiden ob ein Graphics-Objekt von einer JComponent oder einem BufferedImage kommt..? AWT, Swing, JavaFX & SWT 4
A 2D-Grafik BufferedImage wird nicht eingezeichnet AWT, Swing, JavaFX & SWT 3
G 2D-Grafik BufferedImage Hintergrund immer schwarz AWT, Swing, JavaFX & SWT 4
Developer_X Swing Auf ein BufferedImage mit Graphics/Graphics2D zeichnen AWT, Swing, JavaFX & SWT 6
J AWT BufferedImage to 2DArray AWT, Swing, JavaFX & SWT 10
R Bild drehen UND skalieren (Image bzw BufferedImage) AWT, Swing, JavaFX & SWT 5
J JPanel in Bufferedimage AWT, Swing, JavaFX & SWT 3
1 BufferedImage in byte[], dann in String und zurück AWT, Swing, JavaFX & SWT 7
J Swing paintComponent() - repaint() - BufferedImage anzeigen AWT, Swing, JavaFX & SWT 5
C BufferedImage-Fehler? Falsches Bild wir gezeichnet AWT, Swing, JavaFX & SWT 5
B BufferedImage Builder AWT, Swing, JavaFX & SWT 15
F Größe von BufferedImage ändern AWT, Swing, JavaFX & SWT 27
I Swing JComponent als BufferedImage speichern AWT, Swing, JavaFX & SWT 18
Dragonfire Swing Zoom-Vorgang optimieren [BufferedImage] AWT, Swing, JavaFX & SWT 2
2 Memory Leak mit BufferedImage !! AWT, Swing, JavaFX & SWT 15
X BufferedImage maximiert in JFrame anzeigen? AWT, Swing, JavaFX & SWT 2
R JPanel - BufferedImage - zeichnen großer Bilder AWT, Swing, JavaFX & SWT 2
R JTable - TableCellRenderer - BufferedImage AWT, Swing, JavaFX & SWT 9
D BufferedImage und Graphics2D AWT, Swing, JavaFX & SWT 3
R Zeichnen von Zahlen in BufferedImage AWT, Swing, JavaFX & SWT 6
G BufferedImage.getRGB() mit 3 int-Werten vergleichen AWT, Swing, JavaFX & SWT 2
Luma BufferedImage wird nicht gezeichnet AWT, Swing, JavaFX & SWT 3
G keine ScaledInstance von BufferedImage? AWT, Swing, JavaFX & SWT 6
S BufferedImage & Scaling: Altes Problem im neuen Gewand AWT, Swing, JavaFX & SWT 2
G zu viele/große BufferedImage führt zu Java heap space AWT, Swing, JavaFX & SWT 5
G BufferedImage und jpg --> maximale Qualität AWT, Swing, JavaFX & SWT 9
F HTML Text irgendwie auf BufferedImage bringen AWT, Swing, JavaFX & SWT 3
R BufferedImage Problem AWT, Swing, JavaFX & SWT 2
G Problem mit BufferedImage und imageIO AWT, Swing, JavaFX & SWT 2
S BufferedImage drehen AWT, Swing, JavaFX & SWT 3
? ActionListener auf BufferedImage AWT, Swing, JavaFX & SWT 11
M BufferedImage mit html interpretierten String beschriften AWT, Swing, JavaFX & SWT 3
A Probelme mit großen BufferedImage in paintComponent AWT, Swing, JavaFX & SWT 7
B Farbtiefe eines BufferedImage verringern AWT, Swing, JavaFX & SWT 3
F ImageIcon -> BufferedImage AWT, Swing, JavaFX & SWT 2
T Performance Problem bei BufferedImage AWT, Swing, JavaFX & SWT 3
F Animiertes Gif als BufferedImage AWT, Swing, JavaFX & SWT 10
L Anzeigen von fotos: ImageIcon oder BufferedImage + paint() ? AWT, Swing, JavaFX & SWT 5
C Rotate BufferedImage --> Bild unvollständig AWT, Swing, JavaFX & SWT 5
U Streifen hinter bewegtem BufferedImage AWT, Swing, JavaFX & SWT 13

Ähnliche Java Themen

Neue Themen


Oben