2012-10-25 11 views
13

Ho utilizzato i metodi ImageIO.read() e ImageIO.write() in javax.imageio.ImageIO per leggere e scrivere immagini, e ho scoperto che il colore di alcune immagini viene modificato in modo strano.il colore dell'immagine jpeg viene drasticamente modificato dopo solo ImageIO.read() e ImageIO.write()

Anche se cambio il mio codice per non fare altro che leggere le immagini e scriverle (con jpeg, png, gif), tutte quelle nuove immagini hanno lo stesso problema.

Devo aggiungere altro codice prima/dopo i metodi ImageIO.read/write?

Ecco il codice che ho usato:

File f = new File("obw.jpg"); 
    BufferedImage bi = ImageIO.read(f); 
    FileOutputStream fos2 = new FileOutputStream("obw2.jpg"); 
    ImageIO.write(bi, "JPG", fos2); 
    FileOutputStream fos3 = new FileOutputStream("obw3.gif"); 
    ImageIO.write(bi, "GIF", fos3); 
    FileOutputStream fos4 = new FileOutputStream("obw4.png"); 
    ImageIO.write(bi, "PNG", fos4); 

Il mio ambiente:

java version "1.6.0_35" 
    MacOSX 10.8.2 

Immagine originale: enter image description here

Una delle immagini dopo lettura e scrittura:

enter image description here

+0

Quale viene modificato o tutti? l'immagine originale è forse * corrotta *? –

+0

http://stackoverflow.com/questions/2408613/problem-reading-jpeg-image-using-imageio-readfile-file – Lesto

+0

Ho letto l'immagine originale e ho scritto immagini jpeg, png, gif e tutte e tre mostrano che l'obiwan verde ... c'è un modo per controllare se quell'immagine originale è corrotta? – UGO

risposta

22

Il tuo problema è che ImageIO sta interpretando erroneamente i dati YCbCr nel tuo JPEG come dati RBG. I bug Java rilevanti sono 4712797 e 4776576, che Oracle afferma erroneamente che sono stati corretti in Java 1.4, ma in realtà affliggono ancora Java JVM 5, 6 e 7.

In un progetto su cui lavoro, abbiamo risolto questo problema caricando un test JPEG with a single black pixel appositamente creato per verificare se ImageIO lo carica correttamente. Se il pixel diventa verde, ImageIO interpreta erroneamente i dati dell'immagine, quindi quando cariciamo i file JPEG in un secondo momento e rileviamo il tipo di file JPEG che causa il problema, applichiamo anche una correzione del colore. (Il tipo di JPEG che attiva il problema in JVM che lo mostra ha un particolare tipo di sottocampionamento e nessun marcatore JFIF.)

Ecco alcuni LGPLv2-licensed code che si occupa del problema. La necessità di codice come questo per aggirare i bug di decine di anni quando tutto il resto del mondo riesce a caricare correttamente i file JPEG è uno dei motivi per cui voglio che Java muoia in un incendio.

+0

Grazie !! Mi sento molto più sicuro ora !! – UGO

+0

@UGO come si risolve questo problema? –

+4

Ancora non risolto - Sto vedendo questo problema su Java 8. –

Problemi correlati