将PNG转换为JPEG

Nor*_*rto 13 java png jpeg image jai

我在将简单的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;
}
Run Code Online (Sandbox Code Playgroud)

...

我最终得到了一个JAI异常 - > java.lang.RuntimeException:只能写入1或3波段字节数据.在com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148)...

跑出选项.有什么建议吗?

tra*_*god 24

使用它可能更容易ImageIO将PNG读入BufferedImage并以JPEG格式写出图像.

附录:在这种方法中,转换由作者透明地处理ImageTranscoder.

BufferedImage img = ImageIO.read(new File("image.png"));
ImageIO.write(img, "jpg", new File("image.jpg"));
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案并不适用于所有 PNG。请参阅:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4836466。万一链接中断,要点是使用 ImageIO 转换的带有 alpha 的 PNG 会写入具有通常不支持的有效色彩空间的 JPEG。引用:“想要能够写入/读取包含 JPEG 格式的 alpha 通道的图像的开发人员可以使用图像 I/O API 来实现,但需要注意的是,许多本机应用程序不太符合YCbCrA 和 RGBA 格式。” 这里的本机应用程序是指所有浏览器。 (2认同)

Tre*_*son 19

在尝试编写jpg之前,你可能需要在png中使用alpha通道.

创建一个类型为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);
Run Code Online (Sandbox Code Playgroud)


小智 6

我还发现使用 ImageIO (Java 6) 将 PNG 图像读入 BufferedImage 并将其写入 JPG“格式名称”会损坏图像。图像在那里,但颜色看起来“日光化”并且几乎​​是倒置的。JPG 文件肯定比 PNG 文件小很多,所以做了很多压缩。我不知道您如何控制压缩或颜色深度。


jar*_*bjo 5

我假设 JAI 使用索引颜色模型读取 PNG 图像,并且只能将 8 位灰度或 24 位彩色图像写入 JPEG 文件。

如果您不需要为此任务使用 JAI,您应该可以使用 ImageIO 代替:

ImageIO.write(ImageIO.read(new File("in.png")), "JPEG", new File("out.jpg"));
Run Code Online (Sandbox Code Playgroud)


小智 5

使用其他解决方案转换后我损坏了文件,但这种方法对我有用:

    public static void formatConverter(String pngFile, String jpgFile) {
        try {

            File input = new File(pngFile);
            File output = new File(jpgFile);

            BufferedImage image = ImageIO.read(input);
            BufferedImage result = new BufferedImage(
                    image.getWidth(),
                    image.getHeight(),
                    BufferedImage.TYPE_INT_RGB);
            result.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
            ImageIO.write(result, "jpg", output);

        }  catch (IOException e) {
            e.printStackTrace();
        }

    }
Run Code Online (Sandbox Code Playgroud)