pdf.addImage(myPanel)
What this actually does is take a low resolution screenshot (72 DPI) of the component and add it as an image to the pdf. So when you print the pdf, the quality is pretty bad. After some digging I found this post which seemed to be exactly what I was looking for. I thought that simply doing this would do the trick:
var image:ImageSnapshot = ImageSnapshot.captureImage(myPanel, 300, new PNGEncoder());
The problem is caused by the fact that Alive PDF doesn't support transparent PNGs which is what is returned when using the PNGEncoder class which is part of Flex.
A little more digging (several hours worth actually) turned up this post which again sounded like my solution. Applying the code fix from that got me almost there. I created my own NonTransparentPNGEncoder which was basically a copy of the built in PNGEncoder with this new version of internalEncode() method:
private function internalEncode(source:Object, width:int, height:int,
transparent:Boolean = false):ByteArray{// The source is either a BitmapData or a ByteArray.var sourceBitmapData:BitmapData = source as BitmapData;var sourceByteArray:ByteArray = source as ByteArray;if (sourceByteArray)sourceByteArray.position = 0;// Create output byte arrayvar png:ByteArray = new ByteArray();// Write PNG signaturepng.writeUnsignedInt(0x89504E47);png.writeUnsignedInt(0x0D0A1A0A);// Build IHDR chunkvar IHDR:ByteArray = new ByteArray();IHDR.writeInt(width);IHDR.writeInt(height);IHDR.writeByte(8); // bit depth per channelIHDR.writeByte(2); // color type: RGBAIHDR.writeByte(0); // compression methodIHDR.writeByte(0); // filter methodIHDR.writeByte(0); // interlace methodwriteChunk(png, 0x49484452, IHDR);// Build IDAT chunkvar IDAT:ByteArray = new ByteArray();for (var y:int = 0; y <>{IDAT.writeByte(0); // no filtervar x:int;var pixel:uint;for (var j:int = 0; j <>{pixel = sourceBitmapData.getPixel(j, y);IDAT.writeByte(pixel >> 16 & 0xFF);IDAT.writeByte(pixel >> 8 & 0xFF);IDAT.writeByte(pixel & 0xFF);}}IDAT.compress();writeChunk(png, 0x49444154, IDAT);// Build IEND chunkwriteChunk(png, 0x49454E44, null);// return PNGpng.position = 0;return png;}
One final change and I finally had it working:
pdf.addPage();var image:ImageSnapshot = ImageSnapshot.captureImage(page, 300, new NonTransparentPNGEncoder());var resize:Resize = new Resize ( Mode.FIT_TO_PAGE, Position.CENTERED );pdf.addImageStream(image.data, ColorSpace.DEVICE_RGB, resize);
Then I just save my pdf to a ByteArray and use the FileReference to save it.
var bytes:ByteArray = pdf.save(Method.LOCAL);var file:FileReference = new FileReference();file.save(bytes, filename);
Keep in mind that although the panels are high resolution, they are still bitmap graphics. So, you will not be able to copy and paste any of your text out of the resulting PDF.
In order for all this to work, I am using 0.1.5 Beta version of AlivePDF, Flex 3.4 and Flash Player 10.
UPDATE: One last note. Because this is generating a 300DPI version of your component, it takes some time. A few seconds for a few page document.