Durchsichtige Images werden beim kopieren schwarz

  • Themenstarter Themenstarter bones
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
B

bones

Gast
Hi, ich wandle ein Image zu einem Byte[] und verschicke das dann. Aber wenn ich Images rüber schicke die einen durchsichtigen Hintergrund haben, werden die Hintergründe Schwarz. Weiss einer wie ich das umgehen kann?
 
Alpha???

Code:
 public static byte[] imageToByte(File inputfile)
    {
    	try
    	{
BufferedImage srcImage = ImageIO.read(inputfile);
BufferedImage outImage = null;
int height = srcImage.getHeight(), width = srcImage.getWidth();        
 if(srcImage.getHeight() > hNew || srcImage.getWidth() > wNew)
outImage = createBufferedImage(srcImage.getScaledInstance(wNew, hNew, BufferedImage.TYPE_INT_RGB));
else
outImage = srcImage;//createBufferedImage(srcImage.getScaledInstance(width, height, BufferedImage.TYPE_INT_RGB));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
 if(inputfile.getName().toLowerCase().endsWith("gif"))	ImageIO.write((BufferedImage)outImage, "gif", byteArrayOutputStream);
if(inputfile.getName().toLowerCase().endsWith("jpg") || inputfile.getName().toLowerCase().endsWith("jpeg"))	
   ImageIO.write((BufferedImage)outImage, "jpg", byteArrayOutputStream);
if(inputfile.getName().toLowerCase().endsWith("png"))	ImageIO.write((BufferedImage)outImage, "png", byteArrayOutputStream);	
 byte[] imageData = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();

return imageData;
 
Der Alpha-Kanal eines Bildes spiegelt die Transparenz einzelner Pixel wieder.

Was mir auf den ersten Blick auffällt:

1.) Beim skalieren des Bildes gibst du als hint BufferedImage.TYPE_INT_RGB an. WENN diese Angabe korrekt WÄRE, dann müsste es TYPE_INT_ARGB heißten (für die Alpha-Unterstützung). Es ist aber nicht richtig, hier gehört hin, wie skaliert werden soll (z. B. Image.SCALE_FAST oder Image.SCALE_SMOOTH)

2.) Was macht die Methode createBufferedImage?

3.) Wie wird das byte-Array weiter verarbeitet?
 
Hobbit_Im_Blutrausch hat gesagt.:
Der Alpha-Kanal eines Bildes spiegelt die Transparenz einzelner Pixel wieder.

Was mir auf den ersten Blick auffällt:

1.) Beim skalieren des Bildes gibst du als hint BufferedImage.TYPE_INT_RGB an. WENN diese Angabe korrekt WÄRE, dann müsste es TYPE_INT_ARGB heißten (für die Alpha-Unterstützung). Es ist aber nicht richtig, hier gehört hin, wie skaliert werden soll (z. B. Image.SCALE_FAST oder Image.SCALE_SMOOTH)

2.) Was macht die Methode createBufferedImage?

3.) Wie wird das byte-Array weiter verarbeitet?

1)Hatte mit Image.SCALE_SMOOTH probiert aber gleiches Ergebnis. Und jetzt auch mit TYPE_INT_ARGB aber das Bild das Ankommt ist schwarz.

2) Die Methode erzeugt ein BufferedImage mit der größe die ich haben will und das funktioniert auch meistens manche Bilder gehen nicht wenn zb nur die Höhe größer ist als ich in der if Bedingung verlange.

3) Ich baue mir einen HTTP-Requests und verschicke es

Code:
File theFile  = files[i];  
byte [] newb = Utils.imageToByte(theFile);
fis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(newb)));			             		
theData = newb;
fis.readFully(theData);
fis.close();    
long bodysize = -1;

Code:
body_file1_pre.append("" 			             			
+ "--" + boundary + "\n"
+ "Content-Disposition: form-data; name=\"datafile\"; " 
+	"filename=\"" + bildfile.toString() + "\"\n"
+ "Content-Type: image/jpeg\n"
+ "\n");

Code:
cmd_post.append("" 
+ "POST " + path + "?PHPSESSID=" + sessid + " HTTP/1.0\n"
+ "Content-type: multipart/form-data, boundary=" + boundary + "\n"
+ "Content-length: " + bodysize + "\n"
+ "\n");
wr.write(cmd_post.toString());
wr.write(body_fields.toString());
wr.write(body_file1_pre.toString());
wr.flush();
raw.write(theData);
raw.flush();
 
1.) Du sollst dort nicht statische Member der BufferedImage-Klasse verwenden, sondern die der Image-Klasse. Sie geben an, wie skaliert werden soll (performant, schön, ...). Wenn du einen anderen Wert angibst, dann stimmt der entweder zufällig mit einem Skalierungsverfahren überein, oder es wird das Default-Verfahren verwendet. Dort muss also aufjedenfall etwas anderes als TYPE_INT_RGB bzw. TYPE_INT_ARGB rein, da das dort sinnlos ist und nichts verloren hat. Auf die Transparenz hat dieser Parameter ebenfalls keinen Einfluss

2.) Das war mir auch klar, ich würde da nur gerne deinen Code sehen

3.) Du schickst es also an php ... kann natürlich sein, dass php die Transparenz entfernt, weil du einen Fehler in deinem php Code hast ... Da kann ich dir dann nicht weiterhelfen.
 
Glaub nicht das es an PHP liegt weil wenn ich die Bilder so rüber schicke ohne sie von der Größe verändert zu haben dann kommen sie auch normal an. Ich poste mal die aktuelle Version von mir :

Upload.java
Code:
byte[] theData = null;	
File theFile  = files[i]; 
			             		
BufferedImage Image = ImageIO.read(theFile);
			             		
if(Image.getHeight() > Utils.hNew || Image.getWidth() > Utils.wNew)
{
	theData = Utils.imageToByte(theFile);
	fis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(theData)));			             		
}
else
{
	fis = new DataInputStream(new BufferedInputStream(new FileInputStream(theFile)));
	theData = new byte[(int) theFile.length()];    	
}

Utils.java:
Code:
public static byte[] imageToByte(File inputfile)
    {
    	try
    	{
	        BufferedImage srcImage = ImageIO.read(inputfile);
	        BufferedImage outImage = null;
	        outImage = createBufferedImage(srcImage.getScaledInstance(wNew, hNew, BufferedImage.TYPE_INT_ARGB));


	        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
	        if(inputfile.getName().toLowerCase().endsWith("gif"))	ImageIO.write((BufferedImage)outImage, "gif", byteArrayOutputStream);
	        if(inputfile.getName().toLowerCase().endsWith("jpg") || inputfile.getName().toLowerCase().endsWith("jpeg"))	
	        														ImageIO.write((BufferedImage)outImage, "jpg", byteArrayOutputStream);
	        if(inputfile.getName().toLowerCase().endsWith("png"))	ImageIO.write((BufferedImage)outImage, "png", byteArrayOutputStream);

	        byte[] imageData = byteArrayOutputStream.toByteArray();
	        byteArrayOutputStream.close();
	        

	        return imageData;

Wenn ich in der Upload.java if(false) mache statt das von oben schickt er alle Dateien über den FileinputStream und alle Bilder kommen normal an aber es findet leider keine Anpassung der Bilder statt. Deswegen kann es nicht an PHP liegen.

und zu 2) createBufferedImage hab ich nicht geschrieben die ist schon in den Javabibliotheken drin.
 
createBufferedImage ist aber kein Standard-Java - niemand kennt diese Methode. Ich vermute aber, dass in dieser Methode der Fehler liegt.
 
Da steht aber nirgendwo, dass du eine statische Methode der Klasse ImageTypeSpecifier aufrufst -was ich auch irgendwie bezweifle, da du dieser Methode ein "Image" übergibst, diese Methode im ImageTypeSpecifier aber zwei Integer erwartet :roll: .
 
Sorry mein Fehler...

Code:
   public static BufferedImage createBufferedImage(Image image)
    {
    	BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null),
        BufferedImage.TYPE_INT_RGB);    	
    	Graphics2D g = bi.createGraphics();
    	g.drawImage(image, 0, 0, null); 
    	g.dispose();
      return bi;
    }

Hatte immer woanders den Fehler gesucht, ich glaub ich brauch Urlaub :autsch:
 
Wie schon gesagt, heißt TYPE_INT_RGB OHNE Alpha. Du brauchst aber MIT Alpha. Also machst du in deiner Methode aus dem BufferedImage.TYPE_INT_RGB ein BufferedImage.TYPE_INT_ARGB und schon sollte es funktionieren.
 
Code:
  public static byte[] imageToByte(File inputfile)
    {
    	try
    	{
	        BufferedImage srcImage = ImageIO.read(inputfile);
	        BufferedImage outImage = null;
	        outImage = createBufferedImage(srcImage.getScaledInstance(wNew, hNew, BufferedImage.SCALE_SMOOTH));

	        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
	        if(inputfile.getName().toLowerCase().endsWith("gif"))	ImageIO.write((BufferedImage)outImage, "gif", byteArrayOutputStream);
	        if(inputfile.getName().toLowerCase().endsWith("jpg") || inputfile.getName().toLowerCase().endsWith("jpeg"))	
	        														ImageIO.write((BufferedImage)outImage, "jpg", byteArrayOutputStream);
	        if(inputfile.getName().toLowerCase().endsWith("png"))	ImageIO.write((BufferedImage)outImage, "png", byteArrayOutputStream);
	
	        byte[] imageData = byteArrayOutputStream.toByteArray();
	        byteArrayOutputStream.close();
	
	        return imageData; 
    	}
    	catch(Exception e)
    	{
    		e.printStackTrace();
    		return null;
    	}
    }
    
    public static BufferedImage createBufferedImage(Image image)
    {
    	BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null),
        BufferedImage.TYPE_INT_ARGB);    	
    	Graphics2D g = bi.createGraphics();
    	g.drawImage(image, 0, 0, null); 
    	g.dispose();
      return bi;
    }
 
Hm, schaut eigentlich gut aus. Ich ahb gerade kein Java installiert, ich teste das aber nachher mal ausführlich. Wenn sich bis dahin niemand findet, musst du dich wohl noch solang gedulden.
 
Bei welchem Typ von deiner Fallunterscheidung [GIF|JPG|PNG] tritt denn das Problem auf?
JPG kennt keinen Alpha-Kanal und auch GIF wird problematisch sein, da GIF keinen Alpha-Kanal kennt sondern nur eine einzige als transparent definiert Farbe. Einzig PNG sollte also klappen, es koennte aber noetig sein das ueber
diverse ImageWriteParam's noch zu konfigurieren.
 
Hi,

es kommt bei mir einzig und allein bei GIF Bildern vor, das die "transparente" Farbe schwarz gemalt wird und so auf den Server geladen wird.
 
Bei PNG Dateien klappt soweit alles. Nur GIF Dateien wollen nicht gehen aber alles mögliche schon probiert.

Sonst keiner eine Idee?
 
Schon probiert die transparenten Flächen sind dann nicht mehr Schwarz sondern Beige/Grau. Eine Verbesserung aber eigentlich müsste doch noch eine Methode geben das die Farbe Transparent bleibt.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben