您省略的其余代码(ImageIO 保存)以及您正在读取的 PNG 是否具有透明通道(正如 @Daft Punk 指出的那样)是这里的重要部分。
我愿意赌 1 美元,您的 PNG 有一个 alpha 通道,而 JPG 不支持 alpha;不幸的是,Java 的 JPG 编码器不知道忽略您传入的 BufferedImage 上的 Alpha 通道,它会丢弃真实颜色通道 (R/G/B) 之一,转而写出 alpha 值而不是其中一个颜色通道.
例如,如果您有:
ARGB
Java JPG 编码器会写出以下 3 个通道,认为它们是 RGB:
[ARG]
并丢弃蓝色通道。
幸运的是,修复非常简单。只需像这样创建一个 TYPE_INT_RGB 类型的新 BufferedImage:
BufferedImage imageToSave = new BufferedImage(imagemJpg.getWidth(), imagemJpg.getHeight(), BufferedImage.TYPE_INT_RGB);
然后你需要“渲染”带有 Alpha 通道的 BufferedImage,以剥离 Alpha 通道:
Graphics g = imageToSave.getGraphics();
g.drawImage(imagemJpg, 0, 0, null);
现在您可以将生成的 imageToSave 图像保存为 JPG,它看起来会很好。
提示:不要忘记,如果您不喜欢图像的外观(模糊、伪像等),您需要将参数直接传递给 Java JPG 编码器来告诉它不要压缩这么多(read this)——这很少成为问题,但过去当人们说“imgscalr 看起来很糟糕!”时就会出现这种情况。 -- 事实证明 BufferedImage 非常漂亮和清晰,但是 Java 编码器过于激进地压缩结果。
我一直想通过向 imgscalr 库添加一些额外的 IO 帮助程序来解决 Java 图像中这些令人讨厌的小问题,这样您就可以加载文件并保存它们,而不必担心这些琐碎的细节。