Hi-Res Printing in Flash with AlivePDF

Printing with Flash has always been one of those nagging issues I’ve never been able to successfully defeat, using the Flash PrintJob class that is. Although I want to sit here, and tell you how awful the PrintJob class is, I’ll let you try to explore that rocky road all by yourself; When you get to the point when you’re trying to use PixelBender for possibly getting a better algorithm for blending from pixel to pixel, and its still not working let me know, I could’ve saved you like 2 weeks worth of hair pulling by simply telling you to use: AlivePDF.

Once you have the source (or swc) downloaded, and imported into a project there is one important thing to remember, since we’re doing this is PureAS3:
You need to add this to your compiler arguments or it won’t work:

-static-link-runtime-shared-libraries=trueWatch movie online The Transporter Refueled (2015)

Outside of that… Here’s the Code, and a link to download it, as well as use it:

*Thanks to Keith Peters for MinimalComponents

[update] Thanks to Joe Campbell, I’ve added the create.php file that allows you to proxy your save request to a server. This can be useful for two reasons:

  1. If you need to save out of Flash Player 9, this is the only route you have.
  2. If you need to get a preview back before actually saving. I worked on a solution before that converted the output then returned a small preview png.
package com.juanbonfante.blog.demos {
	import com.bit101.components.HBox;
	import com.bit101.components.Label;
	import com.bit101.components.PushButton;
	import com.bit101.components.VBox;
 
	import org.alivepdf.display.Display;
	import org.alivepdf.display.PageMode;
	import org.alivepdf.layout.Layout;
	import org.alivepdf.layout.Mode;
	import org.alivepdf.layout.Orientation;
	import org.alivepdf.layout.Position;
	import org.alivepdf.layout.Resize;
	import org.alivepdf.layout.Size;
	import org.alivepdf.layout.Unit;
	import org.alivepdf.pdf.PDF;
	import org.alivepdf.saving.Method;
 
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.FileReference;
	import flash.net.URLRequest;
 
	/**
	 * @author jbonfante
	 *
	 * This demo is used to show the usage of AlivePDF inside of a PureAS3 file.
	 *
	 * This shows how to print both Images as well as vector art.
	 */
	public class AliveDemo extends Sprite {
		//Define wethere an image has been loaded
		private var _imageLoaded : Boolean = false;
		//Define wether the vectors button has been activated
		private var _vectors : Boolean = false;
 
		//Container for the image display
		private var _imageDisplay : Sprite = new Sprite();
		//Container for the vector display
		private var _vectorDisplay : Sprite = new Sprite();
 
		//Total number of vectors
		private var numVectors : Number = 20;
		//Class member for lading image
		private var loader : Loader = new Loader();
 
		/**
		 * Important: Printing container is the container that is fed into
		 * the AlivePDF instance. Anything we add to printing container gets
		 * added to the print out PDF... with some consequences, but those are
		 * beyond the scope of this tutorial
		 */
		private var _printingContainer : Sprite = new Sprite();
		//PDF Class instance
		private var myPDF : PDF;
		//Label
		private var imgText : Label;
		private var defaultLabel : Label;
		private var myVbox : VBox;
		private var myPrintButton : PushButton;
 
		public function AliveDemo() {
 
			/**
			 * Here we set up the UI items for the class, as well
			 * as add an empty printing container to the stage.
			 *
			 * Setup the button and their listeners
			 */
			addChild(_printingContainer);
 
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
 
			var aHbox : HBox = new HBox();
			var myImageButton : PushButton = new PushButton(aHbox, 0, 0, "Image");
 
			var myVectorButton : PushButton = new PushButton(aHbox, 0, 0, "Vector");
			var myBlendButton : PushButton = new PushButton(aHbox, 0, 0, "Blend");
			myPrintButton = new PushButton(aHbox, 0, 0, "Print");
			var myText : Label = new Label(null, 0, 0, "Alive PDF - Printing Demo - Pure AS3 | for blog.juanbonfante.com");
			myVbox = new VBox();
			addChild(myVbox);
			myVbox.addChild(myText);
			//myVbox.addChild(myPushButton);
			myVbox.addChild(aHbox);
 
			myImageButton.addEventListener(MouseEvent.CLICK, OpenImage, false, 0, true);
			myVectorButton.addEventListener(MouseEvent.CLICK, OpenVector, false, 0, true);
			myBlendButton.addEventListener(MouseEvent.CLICK, ShowBlend, false, 0, true);
 
			defaultLabel = new Label(myVbox,0,0,"Please Make a Selection")
			defaultLabel.scaleX = defaultLabel.scaleY = 3;
		}
 
		/**
		 * Activated when the Blend Button is clicked
		 */
		private function ShowBlend(event : MouseEvent) : void {
			if(_imageLoaded)_printingContainer.addChild(_imageDisplay);
			if(_vectors)_printingContainer.addChild(_vectorDisplay);
 
			if(!_imageLoaded && !_vectors)myVbox.addChild(defaultLabel);
			else if(myVbox.contains(defaultLabel))
			{
				myVbox.removeChild(defaultLabel);
				myPrintButton.addEventListener(MouseEvent.CLICK, CreatePDF, false, 0, true);
			}
		}
 
		/**
		 * Activated when the Vector button is clicked. Auto populates empty container and adds it to the display list
		 */
		private function OpenVector(event : MouseEvent) : void {
			if(_imageLoaded) {
				if(_printingContainer.contains(_imageDisplay))_printingContainer.removeChild(_imageDisplay)
			}
			_vectorDisplay.x = 10;
			_vectorDisplay.y = 50;
			if(!_vectors) {
				for(var i : int = 0 ;i < numVectors ;i++) {
 
					var aChild : DisplayObject = _vectorDisplay.addChild(addVectors());
					aChild.x = Math.random() * 450;
					aChild.y = Math.random() * 800;
				}
				_vectors = true;
			}
			_printingContainer.addChild(_vectorDisplay);
			if(myVbox.contains(defaultLabel))myVbox.removeChild(defaultLabel);
			myPrintButton.addEventListener(MouseEvent.CLICK, CreatePDF, false, 0, true);
		}
		/**
		 * Function to randomly create vector drawing
		 */
		private function addVectors() : DisplayObject {
			var aVector : Shape = new Shape();
			var g : Graphics = aVector.graphics;
			g.beginFill(Math.random() * 0xFFFCCC);
			g.lineTo(0, Math.random() * 90);
			g.lineTo(Math.random() * 180, Math.random() * 75);
			g.lineTo(Math.random() * 13, Math.random() * 5);
			g.lineTo(0, 0);
			g.endFill();
			return aVector;
		}
		/**
		 * Used to load the image one the image button is clicked.
		 *
		 * If the image is already loaded, it is simply displayed.
		 */
		private function OpenImage(event : MouseEvent) : void {
 
			if(!_imageLoaded) {
				var url : String = "assets/demo.jpg";
				var req : URLRequest = new URLRequest(url);
 
				_imageDisplay.addChild(loader);
				//addChild(_imageDisplay);
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, ShowImage);
				_imageLoaded = true;
				loader.load(req);
			} else {
				_printingContainer.addChild(_imageDisplay);
			}
			if(_printingContainer.contains(_vectorDisplay))_printingContainer.removeChild(_vectorDisplay);
			if(myVbox.contains(defaultLabel))myVbox.removeChild(defaultLabel);
		}
 
		private function ShowImage(event : Event) : void {
			_imageDisplay.alpha = 1;
			_imageDisplay.x = 10;
			_imageDisplay.y = 50;
			loader.scaleX = loader.scaleY = .25;
			imgText = new Label(_imageDisplay, 0, 0, "Image reduced to 25%");
			_printingContainer.addChild(_imageDisplay);
			myPrintButton.addEventListener(MouseEvent.CLICK, CreatePDF, false, 0, true);
		}
 
		/**
		 * Initializes AlivePDF class member
		 * and sets up image to printed or previewed
		 * @see http://alivepdf.org for documentation
		 */
		private function CreatePDF(event : MouseEvent) : void {
 
			/**
			 * The PDF Contructor takes the orientation of what you intend to print (i.e. paper orientation),
			 * as well as the units you wish it to measure the paper in,
			 * and the projected dimenstion of the sheet of paper LETTER, LEGAL, A4, etc...
			 */
			myPDF = new PDF(Orientation.PORTRAIT, Unit.POINT, Size.LETTER);
 
			/**
			 * Before we can do anything with our PDF class it needs to contain a Page.
			 */
			myPDF.addPage();
 
			/**
			 * Used to determine how we want our information to fit on the paper.
			 *
			 * Resize takes two variables:
			 * 1: Mode - How to resize: includes FIT_TO_PAGE , NONE, RESIZE_PAGE
			 * 2: Position - How to position resized image: includes CENTERED, LEFT, RIGTH
			 */
			var resMode : Resize = new Resize(Mode.FIT_TO_PAGE, Position.CENTERED);
			/**
			 * This adds a copy of our _priting container with the descriptor set up under resMode.
			 * THis is added to the current page of the PDF (first page in this case)
			 * and gives it a x,y offseet. Which is actually modified in this case by the Position variable
			 */
			myPDF.addImage(_printingContainer, resMode,20,30);
 
			/**
			 * setDisplayMode is used to setup how the PDF will actually open up in the
			 * respective viewer (Acrobat, Preview)
			 * and does not impact the actual print out in any ways
			 */
			myPDF.setDisplayMode(Display.REAL, Layout.SINGLE_PAGE, PageMode.USE_NONE, 1);
			//myPDF.setFont(IFont(FontFamily.ARIAL), 8);
			/**
			 * Setup  file metadata information. This is later written into the PDF headers
			 */
			//#######METADATA
			myPDF.setAuthor("Juan Bonfante | blog.juanbonfante.com");
			myPDF.setCreator("2010 © Juan Bonfante");
			myPDF.setKeywords("Juan Bonfante, AlivePDF, Demo, PureAS3, Flex, Flash, Actionscript");
			myPDF.setTitle("Alive PDF Demo | PureAS3");
			myPDF.setSubject("AlivePDF Demo");
			//#######METADATA
 
			/**
			 * Adds a peice of descriptive text to the document.
			 * You can *cautiously* use this to also format blocks and paragraphs onto your documents
			 * with dynamic text.
			 */
			myPDF.addText('PDF Generated by AlivePDF | blog.juanbonfante.com', 25, 25);
 
			/**
			 * Defines how the PDF should be saved
			 *
			 * By using Method.LOCAL the save function simply returns the newly created ByteArray.
			 *
			 * By using Method.REMOTE you would need a proxy file setup on the server in order to send the byte array
			 * to, and automatically attemps to download it.
			 *
			 * Method.Remote can be used if you don't have access to Flash Player 10
			 * otherwise with the FileReference class under FP10 you can simply just save it out.
			 */
			var output:* = myPDF.save(Method.LOCAL);
			var aFile:FileReference = new FileReference();
			aFile.save(output,"AlivePDFAS3Demo.pdf");
 
                       /**
			* If You wish to output using for Flash Player 9
			* You need to use a proxy in the language of your choice
			* For this example we use PHP
			*
			* Thanks to Joe Campbell for digging it up, since they've
			* been removed from the AlivePDF examples
			* AND COMMENT THE ABOVE 3 lines out
			*/
 
			//myPDF.save( Method.REMOTE, "create.php", "AlivePDFAS3Demo.pdf");
		}
	}
}