# Transparente Bilder mit Graphics zeichnen



## TimeIsTheKey (3. Mrz 2011)

Hallo

Wie kann ich mit Graphics transparente Bilder zeichnen? 
Hier mal meine Code-Schnippsel:

Klasse GameAni:

```
BufferedImage img1,img2;
...
img2 = loadImage("MajinVegeta.PNG");
pan2 = new JImagePanel2("Akteur 1",img2,0,0);
...
pan1.setLayout(null);
pan1.setBounds(0,0,pan1.getImageH(),pan1.getImageW());
...
public BufferedImage loadImage(String ref){
		BufferedImage bimg = null;  
	    try {
	      bimg = ImageIO.read(new File(ref));  
	    } catch (Exception e){  
	      e.printStackTrace();  
	    }  
	    return bimg;
	}
...
```

Klasse JImagePanel2:

```
public class JImagePanel2 extends JPanel{
	private BufferedImage image;
	int x, y;
	int positionx,positiony;
	String name;
	
	public JImagePanel2(String name,BufferedImage image, int x, int y) {
		super();
		this.image = image;
		this.x = x;
		this.y = y;
		this.name = name;
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(image, x, y, null);
	}

// Get-/Set-Methoden für die Variablen
...
}
```

Die Bilder haben einen Charakter drauf mit einem transparenten Hintergrund. Gibt es einen einfachen Weg dies zu ermöglichen? Ich habe auch gehört, dass man durch jeden Pixel im BufferedImage gehen kann um nachzuprüfen, ob es transparent ist und es mit einem Wert zu beschreiben, der in Graphics transparent gezeigt wird. Allerdings weiss ich nicht wie das geht.

Ich habe hier sowieso gleich ein weiteres Problem. Mein Bild hat eine Höhe von 35 px und 77 px in der Breite. Allerdings wird das Bild mit einer Breite von 35 px gelesen und einer Höhe von 77 px. Bei den anderen Bildern klappt es aber. Wo könnte da der Fehler sein?

Achja, wie kann man aus BufferedImage Bereiche ausschneiden? Ich will, falls niemand eine Lösung zum Hauptproblem kennt, versuchen es mit einem JLabel zu lösen und müsste das dafür wissen.

MfG SurviveX


----------



## Marco13 (3. Mrz 2011)

Transparent malen sollte automatisch gehen, aber super.paintComponent löscht meistens den Hintergrund. 
Wenn das Bild gedreht eingelesen wird, hat das meistens den Grund, dass es gedreht IST.
Bereiche "auschneiden"... Es gibt sowas wie BufferedImage.getSubimage (oder so), aber ob das das ist, was du meinst...?


----------



## TimeIsTheKey (3. Mrz 2011)

Marco13 hat gesagt.:


> Transparent malen sollte automatisch gehen, aber super.paintComponent löscht meistens den Hintergrund.
> Wenn das Bild gedreht eingelesen wird, hat das meistens den Grund, dass es gedreht IST.
> Bereiche "auschneiden"... Es gibt sowas wie BufferedImage.getSubimage (oder so), aber ob das das ist, was du meinst...?



Zum 1. Punkt: Was bedeutet meistens? Mir wurde gesagt das dies nicht geht. Wie kriege ich es also hin die Transparenz anzuzeigen?

Zum 2. Punkt: Hmmm... Ich werde aus der Ausgabe mit dem Bild drehen nicht schlau. Ich habe vor diesem transparenten Bild schon ein Bild normal geladen und nach diesem nochmals. Beide Bilder werden normal angezeigt. Wieso sollte es also gedreht sein? ???:L
Apropo. Hier mal ein Screenshot damit du siehst was ich meine:






Zum 3. Punkt: Danke. Genau das habe ich gemeint. Ich dachte ich hätte mir die API gründlich angeschaut, aber anscheinend habe ich das übersehen. :autsch:


----------



## Marco13 (3. Mrz 2011)

Das "meistens" war ein bißchen... sarkastisch  Wenn man ein Bild der Größe 50x100 einliest, dann hat das entweder eine Größe von 50x100, oder es gibt zwei Möglichkeiten:
- Man irrt sich, wenn man glaubt, es wäre 50x100 oder würde mit einer anderen Größe gelesen
- In ImageIO ist ein Fehler, der bewirkt, dass eingelesene Bilder die falsche Größe haben.
Wenn ich wetten sollte... ... ... 

Zum 1. noch ganz allgemein: _Enthält_ das Bild wirklich Transparenz? Kannst mal testweise z.B. http://download.oracle.com/javase/t...Project/src/components/images/dukeWaveRed.gif verwenden, um das Problem ggf. einzugrenzen - PNG is nochmal was (ganz) anderes, aber das wäre ja schonmal ein Anhaltspunkt


----------



## TimeIsTheKey (4. Mrz 2011)

Marco13 hat gesagt.:


> Das "meistens" war ein bißchen... sarkastisch  Wenn man ein Bild der Größe 50x100 einliest, dann hat das entweder eine Größe von 50x100, oder es gibt zwei Möglichkeiten:
> - Man irrt sich, wenn man glaubt, es wäre 50x100 oder würde mit einer anderen Größe gelesen
> - In ImageIO ist ein Fehler, der bewirkt, dass eingelesene Bilder die falsche Größe haben.
> Wenn ich wetten sollte... ... ...
> ...



Hmmm... Irgendetwas stimmt mit meinem PNG nicht. Versuch es mal selbst mit dem (im Anhang). Mit dem dukeWaveRed-Bild wird es nicht umgekehrt angezeigt, aber die Transparenz fehlt. Wie kriege ich es nun mit der Transparenz hin?

Ich würde mich auch schon freuen wenn ich irgend einen Weg finden würde ...


----------



## Marco13 (6. Mrz 2011)

Irgendwie hatte ich schon damit gerechnet, aber ... er zeichnet das Bild halbtransparent über die Linien. Was soll man sagen...

```
import java.awt.image.*;
import java.awt.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.*;


class TransparentTest
{
    public static void main(String args[]) throws Exception
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final BufferedImage image = ImageIO.read(new File("vegetax.png"));
        JPanel p = new JPanel()
        {
            public void paintComponent(Graphics g)
            {
                super.paintComponent(g);
                g.setColor(Color.BLACK);
                for (int i=0; i<100; i+=5)
                {
                    g.drawLine(i,0,i,100);
                }
                g.drawImage(image,0,0,this);
            }
        };


        f.getContentPane().add(p);
        f.setSize(100,100);
        f.setVisible(true);
    }
}
```


----------



## TimeIsTheKey (6. Mrz 2011)

Hmm ... ich versteh nicht ganz was mit diesem Test gezeigt werden soll.


----------



## Marco13 (6. Mrz 2011)

Das Bild, das du gepostet hast, wird dort gezeichnet. Halbtransparent über den Hintergrund, und in der richtigen Größe. Wenn er es bei dir nicht richtig zeichnet, liegt das vermutlich an irgendeinem Fehler im (nicht geposteten) Quellcode...


----------



## TimeIsTheKey (7. Mrz 2011)

Marco13 hat gesagt.:


> Das Bild, das du gepostet hast, wird dort gezeichnet. Halbtransparent über den Hintergrund, und in der richtigen Größe. Wenn er es bei dir nicht richtig zeichnet, liegt das vermutlich an irgendeinem Fehler im (nicht geposteten) Quellcode...



Er wird richtig gezeigt, aber wieso wird er halbtransparent angezeigt? ???:L


----------



## Marco13 (7. Mrz 2011)

In Anlehnung an 


> Wenn das Bild gedreht eingelesen wird, hat das meistens den Grund, dass es gedreht IST.


könnte ich hier sagen: Wenn das Bild halbtransparent angezeigt wird, hat das meistens den Grund, dass es halbtransparent IST  

Es IST eben halbtransparent. Schau es dir z.B. mal in HTML-Seiten der Form

```
<html><body bgcolor=[b]"white"[/b]><img src="vegetax.png" /></body></html>
```
an, und setz' dort statt "white" eben "black", "green", "red" usw. ein: Die Arme und die Hose sind Halbtransparent, und die Hintergrundfarbe schimmert dort durch. Wenn du das nicht willst, wirst du wohl ein Zeichenprogramm bemühen müssen....


----------



## Cola_Colin (8. Mrz 2011)

Hab in einem Anflug von eigenem Interesse an der Problemlage das ganze glaub ich gelöst, was die Transparenz angeht.


----------



## muckelzwerg (8. Mrz 2011)

Verzichte doch erstmal auf das Bild und zeichne ein gewöhnliches Grafikelement. Ein Rechteck, einen Kreis, was auch immer.
Am besten gleich mehrere, die sich überschneiden.
Als Farben gibts Du sowas wie "new Color(1f, 0.f, 0.f, 0.5f))" an.
Erstmal rantasten ob die Transparenz funktioniert, oder ob die Bilder vielleicht im falschen Modus sind.

Danach probierst Du das gleiche mit drawImage().
Wenn es nicht geht. schnappst Du Dir ein Zeichenprogramm und schaust mal in die Bilder rein.


----------



## TimeIsTheKey (8. Mrz 2011)

Marco13 hat gesagt.:


> In Anlehnung an
> 
> könnte ich hier sagen: Wenn das Bild halbtransparent angezeigt wird, hat das meistens den Grund, dass es halbtransparent IST
> 
> ...



Hab nun gesehen das es halbtransparent ist. Ich bin farbenblind. Eventuell ist mir das deswegen nie aufgefallen. Das mit dem halbtransparent sein hat sich gelöst. Dennoch bestehen 2 Probleme. Wieso wird das Bild gedreht? Ich mache nichts mit dem Bild. Was stimmt also mit dem Bild nicht?
Dann wäre da noch das die Transparenz nicht angezeigt wird. Mit einem JLabel wird sie nämlich angezeigt. Siehe:

http://img571.imageshack.us/img571/6553/vegetaxprob.png
http://img13.imageshack.us/img13/6632/transparenzf.png

Mit JLabel:
http://img190.imageshack.us/img190/165/vegetajlabel.png
http://img696.imageshack.us/img696/1608/transduke.png



Cola_Colin hat gesagt.:


> Hab in einem Anflug von eigenem Interesse an der Problemlage das ganze glaub ich gelöst, was die Transparenz angeht.



Danke für die Mühe. Ich versuchs später mit dem Bild ^^



muckelzwerg hat gesagt.:


> Verzichte doch erstmal auf das Bild und zeichne ein gewöhnliches Grafikelement. Ein Rechteck, einen Kreis, was auch immer.
> Am besten gleich mehrere, die sich überschneiden.
> Als Farben gibts Du sowas wie "new Color(1f, 0.f, 0.f, 0.5f))" an.
> Erstmal rantasten ob die Transparenz funktioniert, oder ob die Bilder vielleicht im falschen Modus sind.
> ...



Die Bilder sind nicht im falschen Modus. Mit einem JLabel geht immerhin folgendes:

http://img696.imageshack.us/img696/1608/transduke.png

Graphics hat da irgend ein Problem.


----------



## muckelzwerg (8. Mrz 2011)

Ich verstehe nicht, was Du mit "JLabel" meinst. Erklär mal.
Du kannst Dir auch im Internet andere Bilder mit Transparenz besorgen und mal schauen, ob es mit denen geht.


----------



## TimeIsTheKey (8. Mrz 2011)

muckelzwerg hat gesagt.:


> Ich verstehe nicht, was Du mit "JLabel" meinst. Erklär mal.
> Du kannst Dir auch im Internet andere Bilder mit Transparenz besorgen und mal schauen, ob es mit denen geht.



So mache ich es mit einer Klasse die von JLabel erbt:

```
import java.awt.*;
import java.awt.image.BufferedImage;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Sprite extends JLabel{
	private ImageIcon icon;
	int x,y,positionx,positiony,collisionW,collisionH;
	String name;
	boolean solid;
	
	
	public Sprite(String name,String path, ImageIcon icon, int x, int y, boolean solid) {
		super(icon);
		this.icon = icon;
		this.x = x;
		this.y = y;
		this.positionx = 0;
		this.positiony = 0;
		this.name = name;
		this.solid = solid;
		this.setSize(icon.getIconWidth(), icon.getIconHeight());
	}
	
	public void replace(){
		
	}
	
	public int getImgX(){
		return x;
	}
	
	public void setImgX(int x){
		this.x = x;
	}
	
	public int getImgY(){
		return y;
	}
	
	public void setImgY(int y){
		this.y = y;
	}
	
	public int getPImgX(){
		return positionx;
	}
	
	public void setPImgX(int x){
		this.positionx = x;
	}
	
	public int getPImgY(){
		return positiony;
	}
	
	public void setPImgY(int y){
		this.positiony = y;
	}
	
	public int getImageH(){
		return icon.getIconHeight();
	}
	
	public int getImageW(){
		return icon.getIconWidth();
	}
	
	public String getNameImg(){
		return this.name;
	}

}
```

Hier meine andere Klasse mit JPanel:


```
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class JImagePanel2 extends JPanel{
	private BufferedImage image;
	int x, y;
	int positionx,positiony;
	String name;
	
	public JImagePanel2(String name,BufferedImage image, int x, int y) {
		super();
		this.image = image;
		this.x = x;
		this.y = y;
		this.name = name;
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(image, x, y, null);
	}
	
	public int getImgX(){
		return x;
	}
	
	public int getImgY(){
		return y;
	}
	
	public int getPImgX(){
		return positionx;
	}
	
	public int getPImgY(){
		return positiony;
	}
	
	public void setPImgX(int x){
		this.positionx = x;
	}
	
	public void setPImgY(int y){
		this.positiony = y;
	}
	
	public int getImageH(){
		return image.getHeight();
	}
	
	public int getImageW(){
		return image.getWidth();
	}
	
	public String getNameImg(){
		return this.name;
	}

}
```

Entschuldigung für die Verwirrung.


----------



## Marco13 (8. Mrz 2011)

Marco13 hat gesagt.:


> Transparent malen sollte automatisch gehen, aber super.paintComponent löscht meistens den Hintergrund.



Nimm mal das super.paintComponent da raus...


----------



## TimeIsTheKey (8. Mrz 2011)

Omg. Die Transparenz funktioniert so. :autsch:
Noch eine Idee wieso das Bild gedreht eingelesen wird?


----------



## Marco13 (8. Mrz 2011)

Mach mal direkt nachdem du das Bild eingelesen hast ein
System.out.println(dasBufferedImage);
Dort gibt er dann einen langen, kryptischen String aus. Aber es stehen evtl. interessante Sachen drin.


----------

