2010-02-18 20 views
13

Ho problemi a convertire un PNG semplice in un formato JPEG. Sto utilizzando il seguente codice:Conversione di PNG in JPEG

...

File png = new File(filePath); 
    try { 
     SeekableStream s = new FileSeekableStream(png); 
     PNGDecodeParam pngParams = new PNGDecodeParam(); 
     ImageDecoder dec = ImageCodec.createImageDecoder("png", s, pngParams); 
     RenderedImage pngImage = dec.decodeAsRenderedImage(); 
     JPEGEncodeParam jparam = new JPEGEncodeParam(); 
     jparam.setQuality(0.50f); // e.g. 0.25f 
     File jpeg = new File("jpeg.jpeg"); 
     FileOutputStream out = new FileOutputStream(jpeg); 

     ImageEncoder encoder = ImageCodec.createImageEncoder("JPEG", out, jparam); 

     encoder.encode(pngImage); 

     s.close(); 

    } catch (IOException e) { 
     ok = false; 
     e.printStackTrace(); 
    } 

    return ok; 
} 

...

io alla fine con un'eccezione JAI -> java.lang.RuntimeException: solo 1, o Possono essere scritti dati di byte a 3 bande. a com.sun.media.jai.codecimpl.JPEGImageEncoder.encode (JPEGImageEncoder.java:148) ...

Esaurito dalle opzioni. Qualche suggerimento?

risposta

18

probabilmente avete canale alfa nel png che è necessario sbarazzarsi di prima di tentare di scrivi il jpg.

Creare una nuova immagine di buffer con tipo TYPE_INT_RGB (non TYPE_INT_ARGB), quindi scrivere l'immagine di origine (pngImage) sulla nuova immagine vuota.

Qualcosa di simile (attenzione, non testato il codice):

BufferedImage newImage = new BufferedImage(pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB); 
newImage.createGraphics().drawImage(pngImage, 0, 0, Color.BLACK, null); 
+0

Soluzione elegante. Ha funzionato perfettamente per me. – Norberto

19

Potrebbe essere più facile usare ImageIO per leggere il PNG in un BufferedImage e scrivere l'immagine in formato JPEG.

Addendum: In questo approccio, la conversione viene gestita in modo trasparente dal writer ImageTranscoder.

BufferedImage img = ImageIO.read(new File("image.png")); 
ImageIO.write(img, "jpg", new File("image.jpg")); 
+0

Immagino che la soluzione sia la stessa suggerita sopra. Funziona anche. – Norberto

+1

'La conversione in lettura/scrittura di ImageIO' è implicita; la conversione nell'esempio di Trevor Harrison è esplicitamente esplicita. – trashgod

+0

+1 tecnica abbastanza interessante – stacker

3

ho suppse che JAI legge l'immagine PNG con un modello di colore indicizzato ed è solo in grado di scrivere a 8-bit in scala di grigi o immagini a colori a 24 bit come file JPEG.

Se non è necessario utilizzare JAI per questo compito, si dovrebbe essere in grado di utilizzare ImageIO invece:

ImageIO.write(ImageIO.read(new File("in.png")), "JPEG", new File("out.jpg")); 
+0

Ho provato prima e non funziona. – Norberto

+0

+1 @Norberto: puoi elaborare? Guardando più da vicino, questo è simile a quello che ho usato prima. – trashgod

+0

L'implementazione sopra riportata non funziona come previsto. Non sto insinuando che questo non funzioni affatto. Nel mio caso (immagini con cui sto lavorando) questo non funziona. Non riesce a creare il file previsto e l'output è un valore falso. Apparentemente non è possibile trovare alcun writer adatto per il JPEG. Lo trovo piuttosto strano ma non ho tempo per cercare di capire perché esattamente non funziona. Avrò uno sguardo più da vicino in futuro, ma per sapere che sto mantenendo ciò che funziona. – Norberto

3

ho anche scoperto che la lettura di un'immagine PNG in un BufferedImage con ImageIO (Java 6) e la scrittura fuori per un "nome formato" JPG danneggiato l'immagine. L'immagine era lì, ma i colori sembravano "solarizzati" e quasi invertiti. Il file JPG era sicuramente molto più piccolo del file PNG, quindi è stata eseguita molta compressione. Non vedo come potresti controllare la compressione o la profondità del colore.

+0

Ho avuto lo stesso problema ... piuttosto fastidioso, difficile da eseguire il debug. È su OSX. – jhegedus

1

Stavo ricevendo il seguente messaggio in un contesto leggermente diverso. Liberarsi del canale alfa ha risolto il problema

javax.imageio.IIOException: Sample size must be <= 8 
    at com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:435) 
    at javax.imageio.ImageWriter.write(ImageWriter.java:580) 
    at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageWriter.write(Unknown Source) 
    at net.sf.basedb.util.ImageTools.tiffToJpg(ImageTools.java:98) 
    at net.sf.basedb.util.ImageTools.main(ImageTools.java:118) 
Problemi correlati