# Texturen Deckkraft



## Benny_1995 (27. Nov 2010)

Hi Leute,

Bin gerade dabei einen "Coverflow" zu erstellen und habe ein Problem.
Ich bin ein Anfänger in dem Bereich Java3D und hoffe daher, dass ihr mir helfen könnt.

Ich lade eine Textur (ein Bild mit transparenten Pixeln) auf ein Shape3D. Wie in diesem Tutorial:
http://www.vrupl.evl.uic.edu/LabAccidents/java3d/lesson07/lesson07.java
Als nächstes möchte ich die Deckkraft des ganzen Bildes bzw. der Textur ändern. Dies soll die Spiegelung von meinem Objekt im Coverflow sein.
*Problem:* Ich weiß nicht wie ich die Deckkraft von einer Textur mit transparenten Pixeln verändere.
Hier ein Bild zur Verdeutlichung:





Uploaded with ImageShack.us

Freue mich schon auf eure Vorschläge und Antworten.

Gruß Benny


----------



## Benny_1995 (30. Nov 2010)

Gibts irgendwelche Verständnisprobleme oder warum antwortet keiner? Ich will eigentlich nur wissen ob man bei einem .PNG Bild also mit transparenten Pixeln die Deckkraft verändern kann. Mit den folgenden TrasparentAttributes werden bei einer .PNG-Datei nur die transparenten Pixel unterstützt, sprich die transparenten Flächen sind nicht mehr schwarz:

```
Appearance app = new Appearance ();
	
app = shape.getAppearance ();

TransparencyAttributes ta = new TransparencyAttributes();
ta.setTransparencyMode(TransparencyAttributes.BLENDED);
ta.setTransparency(0.5f);
app.setTransparencyAttributes(ta);
```

Jetzt möchte ich wissen wie man die Deckkraft von dem ganzen Bild verändert.

Gruß Benny


----------



## Marco13 (30. Nov 2010)

Ja, was meinst du? Irgendwas mit der Transparenz stimmt nicht :bahnhof:


----------



## Benny_1995 (1. Dez 2010)

Ich mach mal ein Beispiel:

Ich habe folgendes Bild als Textur geladen:





Uploaded with ImageShack.us

Also ein Bild "ohne transparente Bildfläche". Jetzt kann ich mit folgendem Code die Transparenz des gesamten Bildes ändern:

```
Appearance app = new Appearance ();
    	
    	  app = shape.getAppearance ();
         	TransparencyAttributes ta = new TransparencyAttributes();
      	ta.setTransparencyMode(TransparencyAttributes.BLENDED);
      	ta.setTransparency(0.45f);
      	app.setTransparencyAttributes(ta);
```
Hier in dem Beispiel auf eine Transparenz von 0.45f.

Wenn ich jetzt ein Bild mit transparenten Pixeln nehme, also eine .PNG-Datei, wird nur die Transparenz des Bildes unterstützt. und der Befehl "ta.setTransparency(0.45f)" wird nutzlos.
Hier ein .PNG mit transparenten Pixeln:





Uploaded with ImageShack.us

Wie ändere ich nun die Deckkraft des .PNG Bildes? Ich will dass das Firefoxsymbol durchsichtig wird. Aber der Befehl "ta.setTransparency(0.45f)" bewirkt nichts mehr.


----------



## Marco13 (2. Dez 2010)

OK, es ist schwer zu sagen, woran genau das liegt - das hängt wohl viel mit Implementierungsdetails zusammen, die man so erstmal nicht kennt. Ein spontaner Ansatz wäre, mal zu schauen, bei welchen Bildern das auftritt: Es kann sein, dass schlicht und einfach beim Laden erkannt wird, dass transparente Pixel vorhanden sind, und dann RGBA verwendet wird, und ansonsten nur RGB (und das Setzen der Transparenz eventuell nur bei RGB funktioniert).

Du könntest mal schauen, welcher Effekt bei sowas auftritt (Pseudocode)

```
BufferedImage transparent = ImageIO.read(transparentFile);
BufferedImage opaque = ImageIO.read(opaqueFile);
Texture tImage = new TextureLoader(transparent, this).getTexture();
Texture oImage = new TextureLoader(opaque, this).getTexture();
```
Dann kann man ggf. nachschauen, bei welchem BufferedImage.TYPE_* das ganze funktioniert, und evtl. das Bild, bei dem es NICHT funktioniert, in ein passendes Bild reinmalen. Notfalls könnte man dann auch die Transparenz der Pixel direkt im Bild (statt mit setTransparency) setzen....


----------



## Benny_1995 (2. Dez 2010)

Also ich habe mir mal ein paar Infos über die Bilder ausgeben lassen:

Bild ohne transparenten Pixeln:
getAlphaRaster() :
null
getColorModel() :
ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_ColorSpace@93dee9 transparency = 1 has alpha = false isAlphaPre = false
getTransparency() :
1
getType() :
5

Bild mit transparenten Pixeln:
getAlphaRaster() :
ByteInterleavedRaster: width = 395 height = 497 #numDataElements 1 dataOff[0] = 0
getColorModel() :
ColorModel: #pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@93dee9 transparency = 3 has alpha = true isAlphaPre = false
getTransparency() :
3
getType() :
6

Ich hab noch nachgeschaut nach den Typen. Also 5 = TYPE_3BYTE_BGR und 6 = TYPE_4BYTE_ABGR.
Ich hoffe die Infos hast du gemeint. Wie hast du das eigentlich gemeint mit dem Setzen der Transparenz direkt im Bild? Ich habe mal das Bild mit den transparenten Pixeln in Photoshop gezogen und dort dann manuell die Deckkraft verändert. Dann hab ich es abgespeichert und in mein Programm geladen. Das Bild wurde dann auch transparent angezeigt, nur kann ich leider nicht so arbeiten, da ich ja nicht jedes Bild in Photoshop manuell bearbeiten kann.

Ich hoffe das hilft dir weiter beim Finden einer Lösung 

Gruß Benny


----------



## Marco13 (2. Dez 2010)

Mir? Mir ist eigentlich ziemlich wurscht, ob DU das hinkreigst oder nicht ueh: 

Ja, aber bei einer der beiden Bild-Arten funktioniert es ja - wohl bei TYPE_3BYTE_BGR. Du könntest also das Bild laden, das Standardmäßig den falschen Typ hat, und dann sowas machen wie

```
BufferedImage wrong = ImageIO...
BufferedImage better = new BufferedImage(w,h,BufferedImage.TYPE_3BYTE_BGR);
Graphics g = better.getGraphics();
g.drawImage(wrong,0,0,null);
g.dispose();
```
Dann müßte 'better' ein Bild vom passenden Typ sein, und es könnte funktionieren. Dabei geht natürlich die "originaltransparenz" des Bildes verloren, d.h. damit wäre es nicht möglich, Halbtransparente Stellen des Bildes "noch Transparenter" zu machen. Falls du DAS erreichen willst, müßte man... woah, irgendwie vielleicht mit einem AlphaComposite malen, oder ganz brute force sowas wie

```
for (all pixels rgba of input image)
{
    int alpha = getAlpha(rgba);
    int newAlpha = alpha * 0.4;
    int newRgba = set(rgba, newAlpha);
    image.setRGB(x,y,newRgba);
}
```
Also bei jedem einzelnen Pixel das Alpha ein bißchen verkleinern.

}


----------



## Benny_1995 (3. Dez 2010)

Okay danke für den Vorschlag 
Ich habe es jetzt hinbekommen. Falls es jemanden interessiert ist hier die Lösung:

```
public static BufferedImage transparentImage(BufferedImage img, float transparency) {
		int width = img.getWidth(); int height = img.getHeight();
		BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
		Graphics2D g2d = bufferedImage.createGraphics();
		int rule = AlphaComposite.SRC_OVER;		
    	AlphaComposite ac = AlphaComposite.getInstance(rule,transparency);
    	g2d.setComposite(ac);
		g2d.drawImage(img, 0,0,null);
		g2d.dispose();
	return bufferedImage;
}
```

Danach einfach das BufferedImage als Textur laden.

Gruß Benny


----------

