Transparency support for AlivePDF

We’ve recently been in the process of implementing PDF export support in MoodShare, so i’ve been checking out a few different solutions to accomplish this. The one that stood out was AlivePDF, a 100% client side solution written in AS3 by Thibault Imbert.

However, after getting it up and running within the app, i soon realised that there was a slight problem. It didn’t currently support PNG (or any, for that matter) transparency. After a bit of research i found that this was due to the fact that ‘soft mask’ support had not yet been completed, so decided to finish off the implementation myself, as it was something we couldn’t do without.

‘Soft masks’ are essentially the same as a layer mask in Photoshop. So the transparency of the bitmapData is extracted and used to create an 8-bit grayscale image that will act as a mask for the original image, which itself is then supplied as a 24 bit RGB image. The image that represents the ‘soft mask’ is simply assigned by id to the actual image’s /SMask property, when both images are written to the PDF output ByteArray.

I’ve extended the PDF class and added 2 new methods, addDisplayObject() and addBitmapData().

For the addDisplayObject method, when supplying a DisplayObject, if the ‘imageFormat’ parameter is set to ‘PNG’ (which is the default), then it’s assumed that the resulting image will require transparency support, so a mask is also created using the alpha of the resulting bitmapData.

For the addBitmapData method, any BitmapData supplied that supports transparency (i.e it’s ‘transparent’ property is set to true), will also be outputted with a supporting mask.

I’ve also overriden and modified the addImageStream method, which simply checks the type of the supplied ByteArray and if it finds it to be a PNG of colorType 6 (which means each pixel contains an alpha sample as well as an RGB triple), then it’s decoded into a BitmapData and then processed through the addBitmapData method.

I’ve added a PNGDecoder class to deal with this, but have had a few issues with it. It works fine if you convert an existing BitmapData instance to a PNG ByteArray using the Adobe corelibs PNGEncoder and then convert the resulting ByteArray back to a BitmapData instance using the PNGDecoder.decode() method. But when attempting to decode a PNG that has been loaded straight in as a ByteArray using either the URLLoader (as BINARY) or the URLStream classes it fails. I’ve noticed that the resultant ByteArray from both these loader classes is actually longer than the one produced by the corelibs Encoder? This can be seen by simply commenting out line 128 of Main.as.

Unfortunately this is not something we need at the moment and i don’t have the time to work out what the issue is. So if anyone has any suggestions, i’d be happy to implement them in order to fix this.

I’m also not sure whether this is the most efficient way to deal with this, as you could simply use Loader.loadBytes() to convert the ByteArray to a Bitmap instance and then use that instances bitmapData to add the image to the PDF. However, the reason why i haven’t done this is due to the fact that it then becomes asynchronous. Although this may be a better solution for dealing with larger images.

In order for all of this to work, you MUST use the latest version of the AlivePDF source from the SVN, not the version found on the Downloads page. I’ve also supplied a modified version of the Adobe corelibs PNGEncoder, but this is simply for use in the example (Main.as), it is not used anywhere within the PDF implementation.

Thibault is also aware of this and will hopefully be adding it to the AlivePDF core soon.

The example and source code can be found here.

 

This entry was posted in Actionscript 3, Code, Flash and tagged , , , , , , , . Bookmark the permalink.

5 Responses to Transparency support for AlivePDF

  1. Simon says:

    Thankyou for this, it has saved me in a crunch with a mobile application trying to encode a signature and place it in a pdf… gold sir, gold :)

  2. David Coleman says:

    THANK YOU THANK YOU. I was battling with this for days. You saved my deadline, sir.

  3. Adrian says:

    I just wanted to extend my thanks to you, for adding such a critical feature to an already incredible library of tools. AlivePDF is simply perfect.

    My hats off to you sir!

    Adrian

  4. Hozeee says:

    I have only one question. The pdf size is very big, cause you used bytearray, not png encoded image. My best solutionwas this: image = new RawImage( PNGEncoder.encode(bmd), ColorSpace.DEVICE_RGB, id, bmd.width, bmd.height, bmd.transparent);, but pdfreaders always said, format is wrong…
    (Anyway sometimes photoshop can read it!) So is there any solution for this? Could someone help me? Thank you, it’s a very cool thing anyway!:)

  5. James says:

    I can’t remember exactly, but doesn’t the image get encoded before it get’s added to the pdf anyway? Have you tried this?

    image = new PNGImage( PNGEncoder.encode(bmd), ColorSpace.DEVICE_RGB, id );

    or even possibly

    var jEnc : JPEGEncoder = new JPEGEncoder();
    var jpg : ByteArray = jEnc.encode( bmd );
    image = new JPEGImage( jpg, ColorSpace.DEVICE_RGB, id );

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>