2009-02-26 6 views
4

Je soupçonne que la solution ici est probablement très simple, mais je suis perplexe ...ImageIO.write ne pas enregistrer en tant que gif, mais fonctionne pour les jpgs et pngs?

// Create the buffered image. 
BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); 

// fill image data (works fine) 
ImageIO.write(bufferedImage, "JPG", f1); // works fine 
ImageIO.write(bufferedImage, "PNG", f2); // works fine 
ImageIO.write(bufferedImage, "GIF", f3); // this returns false, creates a broken gif file, but fires no exceptions 

Est-ce que ImageIO.write() fonctionne pas pour gifs? est-ce une sorte de retour au gif étant une chose exclusive de Compuserve? Ou suis-je juste être stupide (je suppose que c'est le dernier :))

+0

Se pourrait-il que votre image utilise plus de 8 bits de couleur, et ne peut donc pas tenir dans un GIF? –

Répondre

3
+0

umm ... Je ne suis pas sûr de ce que je regarde là-bas ... Si cela a du sens pour vous, je ne pense pas que vous seriez assez aimable pour traduire cela en une instruction ou deux sur ce que je devrait réellement être "faire"? –

+0

Je ne suis pas sûr de ce que vous obtenez. Image RVB ne peut pas être simplement enregistré au format GIF, peut-être que vous pourriez utiliser différents types d'images? – iny

5

Pour développer la réponse de Iny:

Ce que vous devez faire est ne pas enregistrer au format GIF, basiquement. GIF est une image à palette de 256 couleurs (d'où sa petite taille de fichier). Si votre image a plus de 256 couleurs, vous devez sous-échantillonner les couleurs à 256 avant d'essayer d'enregistrer. l'encodeur ne le fait pas pour vous, car il ne sait pas quoi faire. il commence probablement à écrire l'image, et une fois qu'il dépasse 256 couleurs, il se retire.

Je pense que vous pouvez le faire kindof comme celui-ci (psuedocode)

// Create the buffered image. 
BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); 

... //fill image data (works fine) 

ImageIO.write(bufferedImage, "JPG", f1); // works fine 

ImageIO.write(bufferedImage, "PNG", f2); //works fine 

// downsample to lower color depth by using BYTE_RGB? 
BufferedImage crappyImage = new BufferedImage(w,h,BufferedImage.TYPE_BYTE_RGB); 
crappyImage.getGraphics().drawImage(bufferedImage, 0, 0, w, h, null); 
// or you could repeat the drawing code above with less colors 


if (!ImageIO.write(crappyImage , "GIF", f3)) 
{ 
    //still too many colors 
    f3.delete(); 
    showError("Could not save as gif, image had too many colors"); 
} 

Si votre code de dessin utilise anticrénelage pour regarder agréable, qui va augmenter la profondeur de couleur sans vous penser. Par exemple, dessiner une ligne bleue diagonale AA'd sur un fond blanc semblerait être 2 couleurs, Color.WHITE et Color.BLUE, mais si vous regardez de près, vous avez tout un tas de nuances de bleu pour se débarrasser de la apparence jaggy de la ligne diagonale.

+0

TYPE_BYTE_RGB n'est pas membre de BufferedImage. TYPE_BYTE_INDEXED (que le doc java semble suggérer comme alternative) ne produit aucun changement à mes résultats. Cependant, je pense que je vais juste passer les gifs et passer à des problèmes plus importants puisque personne n'utilise plus de gifs, de toute façon :) –

+0

c'est pourquoi j'ai dit que c'était psuedocode :) Il y a d'autres comme TYPE_3BYTE_BGR et TYPE_USHORT_555_RGB. Le plus proche serait TYPE_BYTE_INDEXED, à partir de ce que je lis dans le javadocs BufferedImage –

Questions connexes