ImageIO.write non salvare come gif, ma funziona per jpgs e PNG?
-
09-09-2019 - |
Domanda
Ho il sospetto che la soluzione qui è probabilmente molto semplice, ma sono perplesso ...
// 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
La ImageIO.write()
non funziona per gif? È questa una sorta di ritorno al passato gif essere una cosa proprietaria Compuserve? O sono solo di essere stupido (sto cercando di indovinare che è l'ultimo :))
Soluzione
Si noti che GIF può memorizzare solo 256 colori.
Altri suggerimenti
Per espandere sulla risposta di Iny:
Che cosa si dovrebbe fare non è Salvataggio in formato GIF, fondamentalmente. GIF è un'immagine a palette 256 colori (da cui il file di piccole dimensioni). Se l'immagine ha più di 256 colori, è necessario ridurre la risoluzione dei colori a 256 prima di tentare di salvare. l'encoder non lo fa per voi, perché non sa cosa fare. probabilmente inizia a scrivere l'immagine, e una volta che supera i 256 colori, solo balle fuori.
Credo kindof che si possa fare in questo modo (psuedocodarlo)
// 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" );
}
Se il codice di disegno sta usando antialiasing a un aspetto gradevole, che aumenterà la profondità di colore senza di te pensarci. Ad esempio, tracciando una linea blu diagonale AA'd su uno sfondo bianco sembrerebbe essere 2 colori, Color.White e Color.Blue, ma se si guarda da vicino, si ha un sacco di sfumature di blu per sbarazzarsi della aspetto jaggy della linea diagonale.