Beta 4&5, PNGs won't remove background

I’ve been playing with TweakPNG, a Windoze program that lets you view the chunks directly. According to it, the original images are not indexed, but are 24 bit RGB with no Alpha Channel and white (255, 255, 255) specified as the transparent color. They just happen to have < 256 colors.

B.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Thus spake Jeffrey Brent McBeth:

I missed in the spec that there was a length header at the start and a CRC
at the end. Argh.

Ok, so this is an ImageIO bug.


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Thus spake Jeffrey Brent McBeth:

So, that means the output from ImageIO isn’t, strictly speaking, wrong?


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

I’ve submitted an RFE with Sun to get ImageIO’s PNG decoder to honor the tRNS
chunk in 8-bit color type 2 images.

As Sun’s process for resolving bugs would give a glacier a run for its money,
we need to devise a workaround for this problem.

Does anyone know of a simple way to detect whether an image is 8-bit,
color type 2, and has transparent pixels?

One option would be to write a PNG “decoder” which just checks the IHDR chunk
for the bit depth and color type, then if they’re 8 and 2, respectively,
looks for a tRNS chunk and hands the PNG off to Toolkit.createImage() if it
finds one.

Much simpler is to read the metadata from ImageIO, like this:

final ImageInputStream stream = new FileImageInputStream(new File(args[0]));
final Iterator<ImageReader> i = ImageIO.getImageReaders(stream);

final ImageReader reader = i.next();
reader.setInput(stream);

final IIOMetadata md = reader.getImageMetadata(0);
final Node node = md.getAsTree(md.getNativeMetadataFormatName());

final TransformerFactory transfac = TransformerFactory.newInstance();
final Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");

final StringWriter sw = new StringWriter();
final StreamResult result = new StreamResult(sw);
final DOMSource source = new DOMSource(node);
trans.transform(source, result);
final String xmlString = sw.toString();
   
System.out.println(xmlString);

If you run this against the problem image, there’s an IHDR node from which
you can read the bit depth and color type, and there’s a tRNS node from
which we can read the transparent color.

So… I guess we could check the metadata for PNGs we load this way, and
then use Toolkit for the ones where ImageIO won’t respect the transparency.

Thus spake “uckelman”:

I’ve committed a fix for this in trunk 4447 and 4448. It’s not pretty,
but workarounds never are. Based on the timing I did, there’s barely
any difference in the speed of image loading for images which ImageIO
would have loaded successfully, so the only cost of this is the extra
code. In the event that we discover any other images which need to be
loaded by Toolkit instead of ImageIO, it will be easy now to add them
as exceptions.

Try svn4449:

nomic.net/~uckelman/tmp/vassal/


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)