将 ReadableByteChannel 保存为 PNG

Save ReadableByteChannel as PNG

我有一个 ReadableByteChannel,其中包含一个图像(从 URL 或文件中获取)。我最终将 Channel 写入一个文件,代码如下

final FileOutputStream fileOutputStream = new FileOutputStream(outImageName);
fileOutputStream.getChannel().transferFrom(imageByteChannel, 0, Long.MAX_VALUE);
fileOutputStream.close();

由于不清楚图像是 png 还是 jpeg 或...我想确定并将其保存为 png。我知道我可以使用 ImageIO.write(buffImg, outImageName, "png");

但不知何故,这要求 buffImg 是一个 RenderedImage,这就提出了如何获得它的问题?

是否有比使用 ImageIO 从文件系统读取文件并将其写入 png 更简单的解决方案?可以直接在内存中转换吗?

还有一个问题:有没有办法告诉 ImageIO 摆脱 AlphaChannel(=透明)?

如果可以,我建议获取 InputStream 或底层 FileURL 对象而不是 ReadableByteChannel,因为 ImageIO.read(..) 支持所有这些类型直接作为输入。

如果不可能,您可以使用Channels.newInputStream(..)从字节通道获取InputStream,传递给ImageIO.read(...)。无需先写入文件。

代码:

ReadableByteChannel channel = ...; // You already have this
BufferedImage image = ImageIO.read(Channels.newInputStream(channel))

要消除任何不需要的透明度,您可以这样做:

BufferedImage opaque = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = opaque.createGraphics();
try {
    g.setColor(Color.WHITE); // Or any other bg color you like
    g.fillRect(0, 0, image.getWidth(), image.getHeight());

    g.drawImage(image, 0, 0, null);
}
finally {
    g.dispose();
}

您现在可以将 PNG 格式的图像写入文件或流:

if (!ImageIO.write(opaque, "PNG", new File(outputFile)) {
    // TODO: Handle odd case where the image could not be written
}