Transparente Bilder mit Graphics zeichnen

TimeIsTheKey

Aktives Mitglied
Hallo

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

Klasse GameAni:
Code:
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:
Code:
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
 
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...?
 
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:
transfehler.png


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:
 
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
 
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

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 ...
 

Anhänge

  • vegetax.png
    vegetax.png
    2,1 KB · Aufrufe: 201
Zuletzt bearbeitet:
Irgendwie hatte ich schon damit gerechnet, aber ... er zeichnet das Bild halbtransparent über die Linien. Was soll man sagen...
Java:
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);
    }
}
 
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...
 
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
Code:
<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....
 
Hab in einem Anflug von eigenem Interesse an der Problemlage das ganze glaub ich gelöst, was die Transparenz angeht.
 

Anhänge

  • vegetax.png
    vegetax.png
    2 KB · Aufrufe: 146
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.
 
In Anlehnung an

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
Code:
<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....

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

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 ^^

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.

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.
 
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.
 
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:
Code:
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:

Code:
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.
 
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.
 

Zurück
Oben