Flex, PNGs, and PDFs…

At ThoughtFaqtory we are continually encouraged to think outside of the box when challenges are presented.  A challenge was set recently by a pretty innocuous requirement from one of our clients.

This project required me to implement functionality that would allow the end user to export groups of images to PDF. The PDF needed to be high quality, 300 ppi (pixels per inch). After some searching I came across the AlivePDF website which appeared to be perfect for my requirements. Initially after using AlivePDF to generate a few PDFs, I couldn’t believe how easy it was to use and I thought that I had found Utopia. My joy however was short lived after the following error message was received:

error

AlivePDF had no alpha channel support for PNGs and the PNG encoder provided by Adobe always returns a PNG with an alpha channel. Even if you turned off the transparency you will get back a 32 bit ARGB PNG.

I continued searching for someone who had a method of successfully removing the alpha channel but my search proved fruitless. Hence I decided to do my own research into PNGs and found the following:

A valid PNG consists of:

PNG signature
IHDR chunk (only one)
IDAT chunk (one or more)
IEND chunk (only one)

The PNG signature:

89 50 4E 47 0D 0A 1A 0A.

The IHDR image header:

Width: 4 bytes
Height: 4 bytes
Bit depth: 1 byte
Colour type: 1 byte
Compression method: 1 byte
Filter method: 1 byte
Interlace method: 1 byte

The IDAT chunks contain the image data.
The IEND chunk marks the end of the PNG.

The colour type under the IHDR chunk needs to be mentioned here as that is where the image type is defined.

Image type Colour type
Greyscale 0
True colour 2
Indexed colour 3
Grey scale with alpha 4
True colour with alpha 6

After familiarizing myself with PNGs, I revisited Adobe’s PNGEncoder.as class again and eventually managed to make certain changes that allowed the removal of the alpha channel all together.

After all the research this ended up being a lot easier than I had originally thought, all that I needed to do was change the colour type and extract the RGB values. Adobe’s colour type was 6 (True colour with alpha) I changed it to 2 (True colour only). Next I needed to isolate and extract the RGB values, this was done with a bitwise right shift operation and a bitwise AND operation.

// Build IHDR chunk
 
var IHDR:ByteArray = new ByteArray();
IHDR.writeInt(w);
IHDR.writeInt(h);
IHDR.writeUnsignedInt(0x08020000); // True colour (no alpha)
IHDR.writeByte(0);
writeChunk(png, 0x49484452, IHDR);
 
// Isolate RGB values
 
for (var j:int = 0; j < w; j++)
{
	p = img.getPixel(j, i);
	IDAT.writeByte(p >> 16 & 0xFF);
	IDAT.writeByte(p >> 8 & 0xFF);
	IDAT.writeByte(p & 0xFF);
}

The changes implemented resulted in the removal of the Alpha channel which allowed me to successfully embedded the encoded PNG image into a PDF with AlivePDF. This was the first of many problems I had working with PDFs, maybe you will get to read about the others in the not too distant future. Attached below is a sample application that will embed a PNG into a PDF.

[kml_flashembed publishmethod="static" fversion="10.0.0" movie="http://thoughtfaqtory.com/blog/wp-content/uploads/2009/10/pngalpha1.swf" width="630" height="400" targetclass="flashmovie" ]Get Adobe Flash player

[/kml_flashembed]



4 Responses to “ “Flex, PNGs, and PDFs…”

  1. [...] This post was mentioned on Twitter by Simon Barber, ThoughtFaqtory. ThoughtFaqtory said: Flex, PNGs, and PDFs… http://bit.ly/xrqIB [...]

  2. Christophe says:

    Right on. Works great for me. Thanks for the post!

  3. Wayne Posner says:

    Can you please post or email me your source for the internalEncode method where you made the actual changes so I can see exactly what needs to be overridden? The first part is clear, but the second part where you loop to isolate the RGB values is not so clear, especially with the nested loops in the Adobe method.

    Thanks!

  4. Simon says:

    Hi Wayne,

    We can not give out the source as its part of a large client project we are currently working on.

    However, i will speak to one of our developers that wrote the code to send you an email to help you get to the end result.

    Regards,
    Simon

  5. Rob McKeown says:

    I was still have a bunch of problems with this but was eventually able to get it working. A walkthrough is available at http://agileui.blogspot.com/2010/01/high-resolution-pdfs-from-flex.html

  6. [...] use library to create PDF’s directly in Flash Player. There are several posts, i.e. here and here, describing how you can insert a hires image of any DisplayObject, i.e. a chart. These posts tell [...]

Leave a Reply

You must be logged in to post a comment.