2010-02-18 16 views
13

Tengo problemas para convertir un archivo PNG simple a formato JPEG. estoy usando el siguiente código:Convertir PNG a 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; 
} 

...

termino con una excepción JAI -> java.lang.RuntimeException: Sólo 1, o Se pueden escribir datos de 3 bandas de bytes. en com.sun.media.jai.codecimpl.JPEGImageEncoder.encode (JPEGImageEncoder.java:148) ...

se quedó sin opciones. ¿Cualquier sugerencia?

Respuesta

18

es probable que tenga canal alfa en el png que necesita para deshacerse de antes de intentar escribe el jpg

Cree una imagen Buffered nueva con tipo TYPE_INT_RGB (no TYPE_INT_ARGB), y luego escriba su imagen de origen (pngImage) en la nueva imagen en blanco.

Algo como esto (advertencia, no código de prueba):

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

Solución elegante. Funcionó perfectamente para mí. – Norberto

19

Podría ser más fácil de usar ImageIO para leer el PNG en un BufferedImage y escribir la imagen en formato JPEG.

Adición: En este enfoque, la conversión se maneja de forma transparente por ImageTranscoder del escritor.

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

Creo que la solución es la misma que la sugerida anteriormente. También funciona. – Norberto

+1

La conversión de lectura/escritura de 'ImageIO' es implícita; la conversión en el ejemplo de Trevor Harrison es informativamente explícita. – trashgod

+0

+1 técnica bastante genial – stacker

3

I suppse que JAI lee la imagen PNG con un modelo de color indexado y sólo es capaz de escribir en escala de grises de 8 bits o imágenes en color de 24 bits como archivos JPEG.

Si usted no está obligado a utilizar JAI para esta tarea, debe ser capaz de utilizar ImageIO lugar:

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

He intentado esto antes y no funciona. – Norberto

+0

+1 @Norberto: ¿Pueden dar más detalles? Mirando más de cerca, esto es similar a lo que he usado antes. – trashgod

+0

La implementación anterior no funciona como se esperaba. No estoy implicando que esto no funcione en absoluto. En mi caso (imágenes con las que estoy trabajando) esto no funciona. No puede crear el archivo esperado y el resultado es un valor falso. Aparentemente no puede encontrar ningún escritor adecuado para el JPEG. Lo encuentro bastante extraño, pero no tengo tiempo para tratar de descubrir por qué exactamente no está funcionando. Voy a tener una mirada más cercana en el futuro, pero sé que sigo con lo que funciona. – Norberto

3

también encontró que una imagen PNG lectura en un BufferedImage con ImageIO (Java 6) y escribirlo a un "nombre de formato" JPG corrompió la imagen. La imagen estaba allí, pero los colores parecían "solarizados" y casi invertidos. El archivo JPG era mucho más pequeño que el archivo PNG seguro, por lo que se realizó mucha compresión. No veo cómo puede controlar la compresión o la profundidad de color.

+0

Tuve el mismo problema ... bastante molesto, difícil de depurar. Está en OSX. – jhegedus

1

Recibí el siguiente mensaje en un contexto ligeramente diferente. Deshacerse del canal alfa resolvió el 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)