将 PNG 转换为 JPEG

发布于 2024-08-22 01:24:51 字数 1030 浏览 5 评论 0原文

我在将简单的 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 段字节数据。 在 com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148) ...

没有选项。有什么建议吗?

I'm having problems converting a simple PNG into a JPEG format.
I'm using the following code:

...

    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;
}

...

I end up with an JAI exception ->
java.lang.RuntimeException: Only 1, or 3-band byte data may be written.
at com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148) ...

Ran out of options. Any suggestion?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

与风相奔跑 2024-08-29 01:24:51

使用 ImageIO 将 PNG 读入 BufferedImage 并以 JPEG 格式写出图像。

附录:在这种方法中,转换由作者的 ImageTranscoder

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

It might be easier to use ImageIO to read the PNG into a BufferedImage and write the image out in JPEG format.

Addendum: In this approach, the conversion is handled transparently by the writer's ImageTranscoder.

BufferedImage img = ImageIO.read(new File("image.png"));
ImageIO.write(img, "jpg", new File("image.jpg"));
傲娇萝莉攻 2024-08-29 01:24:51

在尝试写入 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);

you probably have alpha channel in the png that you need to get rid of before trying to write the jpg.

Create a new BufferedImage with type TYPE_INT_RGB (not TYPE_INT_ARGB), and then write your source image (pngImage) onto the new blank image.

Something like this (warning, not tested code):

BufferedImage newImage = new BufferedImage( pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newImage.createGraphics().drawImage( pngImage, 0, 0, Color.BLACK, null);
GRAY°灰色天空 2024-08-29 01:24:51

我还发现使用 ImageIO (Java 6) 将 PNG 图像读入 BufferedImage 并将其写入 JPG“格式名称”会损坏图像。图像就在那里,但颜色看起来“日晒”并且几乎​​颠倒了。 JPG 文件肯定比 PNG 文件小得多,因此进行了大量压缩。我不知道你如何控制压缩或颜色深度。

I also found that reading a PNG image into a BufferedImage with ImageIO (Java 6) and writing it out to a JPG "format name" corrupted the image. The image was there, but the colors looked "solarized" and almost inverted. The JPG file was much smaller than the PNG file for sure, so a lot of compression was done. I don't see how you might control the compression or color depth.

囍笑 2024-08-29 01:24:51

使用其他解决方案转换后,我的文件已损坏,但此方法对我有用:

    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();
        }

    }

I had corrupted file after conversion with other solutions but this method worked for me:

    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();
        }

    }
满栀 2024-08-29 01:24:51

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

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

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

I suppse that JAI reads the PNG image with an indexed colour model and is only able to write 8-bit grayscale or 24-bit colour images as JPEG files.

If you are not required to use JAI for this task, you should be able to use ImageIO instead:

ImageIO.write(ImageIO.read(new File("in.png")), "JPEG", new File("out.jpg"));
不可一世的女人 2024-08-29 01:24:51

我在稍微不同的上下文中收到以下消息。摆脱 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)

I was getting the following message in a slightly different context. Getting rid of the alpha channel solved the problem

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)
时光清浅 2024-08-29 01:24:51

参阅使用java将透明gif / png转换为jpeg

请 查看harmanjd发布的使用图形环境重绘的解决方案。使用 DirectColorModel 的解决方案无法编译,应将其清除。我没有足够的代表点来直接发表评论。

see Converting transparent gif / png to jpeg using java

Have a look at the solution that redraws with the graphics environment posted by harmanjd. The solution with the DirectColorModel doesn't compile and should be wiped away. I don't have enough rep points to comment directly there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文