2010-02-18 148 views
13

我在将简单的PNG转换为JPEG格式时遇到了问题。 我使用下面的代码:将PNG转换为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; 
} 

...

我结束了一个JAI例外 - > 了java.lang.RuntimeException:只有1个,或可以写入3段字节数据。 at com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148)...

Ran out of options。任何建议?

回答

18

你可能在你需要尝试之前摆脱PNG alpha通道写jpg。

创建一个类型为TYPE_INT_RGB(不是TYPE_INT_ARGB)的新BufferedImage,然后将源图像(pngImage)写入新的空白图像。

像这样的东西(警告,没有经过测试的代码):

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

优雅的解决方案。它对我来说非常合适。 – Norberto 2010-02-22 11:43:53

19

使用ImageIO可能更容易将PNG读取到BufferedImage中,并将图像以JPEG格式写出。

附录:在此方法中,转换由作者的ImageTranscoder透明处理。

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

我想你的解决方案是与上面建议的相同。它也可以。 – Norberto 2010-02-22 11:45:21

+1

'ImageIO'的读/写转换是隐含的;特雷弗哈里森的例子中的转换信息明确。 – trashgod 2010-02-22 12:55:13

+0

+1挺酷的技巧 – stacker 2010-02-25 21:09:17

3

我suppse是JAI与索引颜色模型读取PNG图像,并且只能够写8位灰度或24位彩色图像为JPEG文件。

如果你不使用JAI这个任务所需要的,你应该能够使用的ImageIO来代替:

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

我以前试过这个,它不起作用。 – Norberto 2010-02-22 11:43:11

+0

+1 @Norberto:你能详细说明一下吗?仔细观察,这与我之前使用过的类似。 – trashgod 2010-02-26 01:50:00

+0

上述实现不能按预期执行。我并不是暗示这根本不起作用。在我的情况下(我正在使用的图像)这不起作用。无法创建预期的文件,输出是错误的值。显然,它找不到任何合适的JPEG作家。我觉得这很奇怪,但我没有时间去弄清楚为什么它不起作用。我将在未来更仔细地看看,但要知道我遵守的是什么。 – Norberto 2010-03-01 11:34:54

3

我还发现,读取PNG图像与ImageIO的(Java 6中)一个BufferedImage,写出来的JPG“格式名称”损坏了图像。图像在那里,但颜色看起来“日晒”,几乎倒过来。 JPG文件确实比PNG文件小得多,因此完成了大量的压缩。我看不出你如何控制压缩或颜色深度。

+0

我有同样的问题...很烦人,很难调试。它在OSX上。 – jhegedus 2017-03-22 01:03:57

1

我在略有不同的上下文中收到以下消息。摆脱alpha通道解决了这个问题

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)