La conversion de transparents, gif, png, jpeg à l'aide de java
J'aimerais convertir en gif pour les images au format jpeg à l'aide de Java. Il fonctionne très bien pour la plupart des images, mais j'ai une simple image gif transparente:
Entrée image gif http://img292.imageshack.us/img292/2103/indexedtestal7.gif
[Dans le cas où l'image est manquant: c'est un cercle bleu avec des pixels transparents autour d'elle]
Quand je convertir cette image en utilisant le code suivant:
File file = new File("indexed_test.gif");
BufferedImage image = ImageIO.read(file);
File f = new File("indexed_test.jpg");
ImageIO.write(image, "jpg", f);
Ce code fonctionne sans jeter une Exception, mais les résultats d'un invalide image jpeg:
[Dans le cas où l'image est manquant: IE ne peut pas afficher les images au format jpeg, Firefox affiche l'image invalide couleurs.]
Je suis à l'aide de Java 1.5.
J'ai aussi essayé la conversion de l'échantillon gif png avec gimp et en utilisant le png comme une entrée pour le code Java. Le résultat est le même.
Est-ce un bug dans le JDK? Comment puis-je convertir des images correctement, de préférence sans les 3e partie les bibliothèques?
Mise à JOUR:
Réponses indiquent que la conversion en jpeg ne peut pas gérer la transparence correctement (je crois que c'est un bug) et de proposer une solution de contournement pour remplacer les pixels transparents de couleurs prédéfinies. Les deux méthodes proposées sont assez complexe, j'ai donc mis en place une plus simple (publierons comme réponse). J'accepte la première publication de réponse avec cette solution de contournement (par Markus). Je ne sais pas laquelle est la mieux. Je vais au plus simple encore, j'ai trouvé un gif où il ne fonctionne pas.
Vous devez vous connecter pour publier un commentaire.
Pour Java 6 (et 5 aussi, je pense):
g
àBufferedImage
de nouveau?Comme déjà mentionné dans la mise à JOUR de la question que j'ai mis en place un moyen plus simple de remplacer les pixels transparents de couleurs prédéfinies:
et j'appelle cette méthode avant de conversion en jpeg de cette façon:
Le problème (au moins avec les png en jpg conversion), c'est que le schéma de couleur n'est pas la même, parce que les jpg ne gère pas la transparence.
Ce que nous avons fait avec succès est quelque chose le long de ces lignes (c'est tiré à partir de différents morceaux de code - veuillez pardonner la crudité de la mise en forme):
Cela fonctionne pour les png en jpg et les gif vers jpg. Et vous aurez un fond blanc où la transparence bits étaient. Vous pouvez modifier cela en ayant g2 remplir l'image avec une autre couleur avant le drawImage appel.
3 mois de retard, mais j'ai un problème très similaire (bien que pas même le chargement d'un gif, mais le simple fait de produire une image transparente - dire, pas de fond, couleur, forme, où lors de l'enregistrement en jpeg, toutes les couleurs sont foiré, non seulement l'arrière-plan)
Trouvé ce bout de code dans ce vieux fil de la java2d-liste d'intérêt, j'ai pensé partager, car après un test rapide, il est beaucoup plus performants que votre solution:
Malheureusement, je ne peux pas dire que je comprends exactement ce qu'il fait 😉
final DirectColorModel cm = (DirectColorModel) img.getColorModel();
semble être un impossible cast -- modèle colorimétrique ne peut pas être lancée à DirectColorModel (j'ai essayé le code et a obtenu un casting d'exception à l'exécution)Si vous créez un BufferedImage de type BufferedImage.TYPE_INT_ARGB et de les enregistrer au format JPEG choses bizarres qui en résultera. Dans mon cas, les couleurs sont scewed en orange. Dans d'autres cas, l'image produite peut-être pas valide et d'autres lecteurs vont refuser de le charger.
Mais si vous créez une image de type BufferedImage.TYPE_INT_RGB puis de le sauvegarder au format JPEG fonctionne très bien.
Je pense que c'est donc un bug de Java image JPEG écrivain - qu'il doit écrire seulement ce qu'il peut sans transparence (comme quoi .NET GDI+ t). Ou dans le pire des cas, la levée d'une exception un message par exemple, "ne peut pas écrire une image qui a de la transparence".
JPEG n'a pas de support pour la transparence. Alors, même si vous obtenez le cercle de couleur correctement, vous aurez toujours un fond noir ou blanc, selon votre codeur et/ou moteur de rendu.