如何从BufferedImage创建8位PNG?

时间:2012-10-11 18:49:24

标签: java png bufferedimage

我有一个Java程序,可以创建仅包含黑色像素和100%透明像素的复合png图像。我试图尽可能地减小这些复合材料的尺寸,我注意到ImageIO.write总是输出32位PNG。我想将它们保存为8位,考虑到图像总共只有两种颜色,但我认为没有办法用标准的Java函数来做到这一点。

有没有人知道任何可以从BufferedImage创建8位png的预构建函数?任何其他减少这些png大小的建议也是受欢迎的!

2 个答案:

答案 0 :(得分:2)

我不确定,但我猜我会ImageIO使用BufferedImage使用的类型。尝试使用不同类型的可用游戏。 TYPE_CUSTOMTYPE_BYTE_BINARY看起来很有希望。

答案 1 :(得分:1)

我不得不把它放在后座上一点,但我昨天回到它并想出了如何做到这一点。基本上,它归结为使用com.sun.imageio.plugins.png下的类和自定义ImageWriteParam

我必须自己构建颜色表(不是太难,只是字节数组)。然后将颜色表传递给ImageTypeSpecifier.createIndexed。返回的结果ImageTypeSpecifier允许您创建我复制像素的BufferedImage

接下来,我使用PNGMetadata创建了自定义PNG标头(需要在PNG规范上阅读很多内容,但总体而言非常简单)。然后,我使用所述元数据和BufferedImage创建了一个新的IIOImage

最后,我创建了一个PNGImageWriter并从中获得了默认的ImageWriteParam。然后,我只是将之前的ImageTypeSpecifier传递给setDestinationType方法。最后一步是通过将IIOImage和ImageWriteParam传递给PNGImageWriter将PNG写入磁盘。

许多这些类的文档非常稀疏,但它们的功能很棒。通过这样做,我创建了一个包含1位深度的最小PNG(因为只有两种颜色),这使我的PNG的大小平均减少了78%!非常值得努力。