Printing in Flash (in 1,000,000,000 simple steps)

If there is one thing that really irritates me, it is when programmers and developers write tutorials or help sections that are targeted to users with the same level of expertise as themselves. Granted some skill sets do require a certain degree of knowledge, and tasks related to specific applications can vary between novice, intermediate, and expert. However, Help documentation should not be written with the assumption that he/she understands the application fully. Help documentation should be more than just reference information. In fact, a reference section should be a separate appendices that can be easily scannable.

In writing the LiveDocs, Printing a Page, the Flash developers have provided some information on how to use the PrintJob class as part of AS 3.0. The problem is that for the novice user, some of this seems like Ancient Greek, or possibly Sanskrit.

Part 1: Printing with the PrintJob Class

In Flash, it is possible to create a function to:

  • Start a print job
  • Adding additional pages
  • Check to see if the user has canceled the print job
  • Specify whether to use bitmap or vector rendering
  • Set the page size, scale, and orientation
  • Specifying the printable area of content
  • Converting screen size to page size
  • Printing multipage print jobs

LiveDocs, Basics of Printing

Since there is so much to cover, this tutorial is only intended to scratch the surface of the PrintJob class. We will focus primarily on starting a print job and sending a page to the printer, specifying whether the print job should be a bitmap or vector rendering, and specifying the print area.

Before we begin we need something to print. Since we have been using custom classes, I included the Splat.as file from Module 8 and the Pi.as (or Ball.as depending on how others named the file). Let’s get started.

  1. docclassOpen up a new Flash AS3.0 fla file. Save this file as prj_print1.fla to a new folder labeled [lastname]_printTutorial. Next create a new AS3 .AS file and name it PrintExample1.as. Be sure to set the Document class of prj_print1.fla to the new AS file.
  2. In our PrintExample1.as file, lets import the packages and classes we will need to print a page. Here I have just added wild cards (*) of the printing, display, and events packages. I could have just been really specific and put import flash.printing.PrintJob, but I like to have my code as flexible as possible in development. Later when, I am done I will go through and clean up the code to be more specific, but for now this works for me.
    package {
    
    	import flash.printing.*;
    	// This will add the PrintJob, PrintJobOptions,
    	// and PrintJobOrientation classes
    
    	import flash.display.*;
    	// This is to import the Sprite class. I probably
    	// just list Sprite, but I will wait until all is done
    
    	import flash.events.*;
    	// And this adds any event I may need to
    	// create my necessary event handlers
    
    }
  3. Next, it’s time to create our custom class
    public class PrintExample1 extends Sprite
  4. If we are going to print something, we will need something to print. Pretty obvious? If we don’t define our content, then the end result will be just a blank page. That works in a minimalistic, David Byrne kinda way, but let’s see what we are doing.I create a new Sprite called _content to contain all my content.
    private var _content:Sprite = new Sprite();
  5. The next thing I want to do is pull in actual content to be printed. For this exercise I pulled in the Splat.as from Module 8, and the Ball.as (or Pi.as) from Module 9. Any will do. In fact, the TextField class, Rectangle class, and MovieClip Class can also be added, but for simplicity I chose two simple assignments from previous modules. I also created a PrintButton symbol and linked it as a class. So let’s call those classes:
    public var pi:Pi;
    public var twinkles:Splat;
    private var printBtn:PrintBtn;
  6. Now that we have our custom classes called into our PrintExample1 file, lets create our function. Note, for the most part this is all review.
    public function PrintExample1(){ // Let's create our function
    	// First add the Print button. I am adding it
    	// outside of the _content Sprite because I don't
    	// want it to show up in my print out
    	printBtn = new PrintBtn();
    	printBtn.x = 18;
    	printBtn.y = 510;
    	printBtn.width = 108.2;
    	printBtn.height = 30;
    	addChild(printBtn);
    
    	// Next create the printJob handler
    	printBtn.addEventListener(MouseEvent.MOUSE_UP, printJob);
    
    	// Now add the _content Sprite to the stage
    	addChild(_content);
    
    	// Add the tinkles Splat to the _content Sprite
    	twinkles = new Splat();
    
    	_content.addChild(twinkles);
    	// Add my circle and tell the compiler what properties
    	//  (color, size and position) I want the circle to
    	pi = new Pi(0xFFCC00, 75);
    	pi.x = 30;
    	pi.y = 30;
    	pi.alpha = .65;
    	_content.addChild(pi);
    }
  7. The last thing we need to do is to create our printJob function
    private function printJob(event:MouseEvent) {
    	// Call the _print instance as part of the PrintJob class
    	var _print:PrintJob = new PrintJob();
    
    	// Starts the OS's printing process by opening the printer
    	// dialogue, adding the read-only properties,
    	// and prepares the page to be sent to the spooler
    	_print.start();
    
    	// addPage add what is actually going to be printed
    	// (the Sprite object and any subsequent children)
    	_print.addPage(_content);
    
    	// send finishes the print job and send the page
    	// to the print spooler.
    	_print.send();
    }
  8. To quote Martha, “SAVE! Test the movie. (Control -> Test movie or Command/Control + return).” Try to print.

You can see an example of Part 1 here

Part 2: Vector or Bitmap (PrintJobOptions)

So now I have my PrintJob class constructed. Its working fine, I can print to whichever printer I choose — I am happy. By default, Flash is setup to tell the printer that everything in a printable area should be rendered as vector art. What if you want to add an JPEG image or Gif or PNG or whatever flavor of bitmapped imagery you may have. Well, you need to tell Flash to tell the printer to render the printer as a bitmap, and you do that with the PrintJobOptions. PrintJobOptions has one main property — printAsBitmap. This property is a boolean type meaning it is either true, or it is false. By default, as I said earlier, the printAsBitmap property is set to false rendering all imagery as vector art. If we wanted to render the artwork as bitmap, we just set the value to true. Here’s how.

  1. First, save prj_print1.fla as prj_print2.fla, and PrintExample1 as PrintExample2. Make the necessary changes in regards to Document class and packages.
  2. Next, I added an imag of an album, set the linkage so that the album was now a custom Album class, added the class as variable to PrintExample2.as as public var album:Album; and added some properties to make the everything pretty.
    var scale:Number = 234;
    album = new Album();
    album.x = 421;
    album.y = 127;
    album.width = scale;
    album.height = scale;
    album.rotation += 7;_content.addChild(album);
  3. I then add following lines to my print function.
    var printOption:PrintJobOptions = new PrintJobOptions();
    printOption.printAsBitmap = true;
    // renders the print job as a bitmap rather than a vector.
  4. The last thing I need to do is to tell the print job how to handle it. The addPage() method actually passes several function. The first is what is to be printed, the second is the area to print, or printArea which will be covered shortly, the third is PrintJobOptions, and the fourth is the frame number to print. It is important to note that the arguments need to be passed in this order:
    addPage(sprite:Sprite, printArea:Rectangle = null, options:PrintJobOptions = null, frameNum:int = 0)
  5. You can decide which ones to pass, but you must follow this order. You can ommit the ones on the end if there is no change to their default value, but you cannot remove the ones in the middle (at least this is how I understand it). For example:
    _print.addPage(_content, null, printOption);
    // null is the value for the printArea property
    // and will be covered in the next lesson. Notice that I
    // ommited the frameNum property. If I were,
    // to include it, I would simply write
    // (_content, null, null, myFrameNum);
  6. The final print job function should look like this:
    private function printJob(event:MouseEvent) {
    	var _print:PrintJob = new PrintJob();
    	_print.start();
    	var printOption:PrintJobOptions = new PrintJobOptions();
    	printOption.printAsBitmap = true;
    	_print.addPage(_content, null, printOption);
    	_print.send();
    	_print = null;
    }
  7. To quote Martha, “SAVE! Test the movie. (Control -> Test movie or Command/Control + return).” Try to print.

You can see an example of Part 2 here

Part 3: The printArea

The last thing that I want to demostrate is the the printArea. The printArea does exactly what it sounds like it does, defines the print area. More importantly it helps to set the size of your print job. If you have a flash movie that you know is bigger than a typical page, and only want to print part of it, then you can define the printArea. This tells the Flash compiler, the OS, and the printer only to print that one part that you have defined. This two is pretty easy and can be done with a few modification.

  1. First, resave prj_print2.fla and PrintExample2.as as prj_print3.fla and PrintExample3. make any necessary class changes.
  2. Next, lets go ahead and deine our specific classes:
    import flash.printing.PrintJob;
    	import flash.printing.PrintJobOptions;
    	import flash.printing.PrintJobOrientation;
    	import flash.display.Sprite;
    	import flash.events.MouseEvent;
    
     	// And to help finish out are printArea we add the
    	// Rectangle class.
    	import flash.geom.Rectangle;
  3. Next, we add a new variable to our variable list called content area:
    private var contentArea:Rectangle = new Rectangle(0,0,550,550);
    // We have positioned this new Rectangle to fall at
    // 0x and 0y and have a dimension of 550px by 550px.
    // This will be our printArea.
  4. Finally, we need to tell the addPage() params that there is now a print area:
    _print.addPage(_content, contentArea, printOption);
  5. To quote Martha, “SAVE! Test the movie. (Control -> Test movie or Command/Control + return).” Try to print.

You can see an example of Part 3 here

Complete versions of the source code used for this tutorial: Print Tutorial Files (.zip)

Resources
Adobe Live Docs: Basics of Printing
ActionScript 3.0 Language and Components Reference

NoPonies by PonyForXmas: ActionScript 3 Print all Items on Stage

Related Posts

14 Responses

  1. Nice job,

    Where the heck was this 6 months ago when I was figuring out the damn print class? It certainly would have made life easier.

    You should send Adobe the complaint about their help, they either leave off the correct syntax and just describe it like you should know what it is, or bury the one line of code in a cool little bit of demo code, the print job being one of the most annoying ones.

  2. Great article. I’m not stupid, but I feel that way when I try to understand the HELP in Flash. I’m glad there are people, who can put it into the simple terminology that it rightly deserves. Thanks. You’d think that Adobe doesn’t want us to understand AS 3. Thanks.

  3. Great tutorial! As a teacher, I completely agree with your concern that documentation isn’t often well scaffolded for the novice. In my case, I have extensive AS3 experience, but have been having trouble with a blue cast that appears over my printer’s output. I tried your example on the web, and it worked great. Looking quickly at your source code, it looked identical to mine. So I downloaded your work, tried printing locally and voila, yours turned out blue too! So apparently, something happens when printing locally as opposed to on a server (running my swf on my localhost solved the problem… I’m running Leopard… not sure if this is an issue in Windows). Had it not been for your well thought out tutorial and, most importantly, inclusion of your source files, I’d still be resolving this problem.

    Thanks!

  4. HELP …. something ‘dumb’ is happening !

    I have ….

    import flash.printing.*;
    import flash.display.*;
    import flash.text.TextField;

    private function PrintLocal():void {
    var pj:PrintJob = new PrintJob();}

    and am receiving a;
    1046 : Type as not found or was not a compile-time constant:PrintJob
    1180 : Call to a possible undefined method PrintJob

    What is going wrong ?

  5. awesome!!!!!! I’ve been looking for this for over 1 week. Thank you so MUCH!!!!!

    Perhaps you could help me with a little something.

    I have a question. How can you specify the print area by using a MC.

    Lets say your stage is 612 by 500 and you have a movie clip called “Crop” now this movie clip is drag-able. so the user can move the clip around and position it where ever they want. now when they click print only that specific area get printed. Let’s say to an 8.5 by 11 piece of paper. you would need your crop area to be they same ratio as an 8.5 by 11 to ensure there no skewing or distortion.

    1. Interesting question. I haven’t thought about it. I think you would have to make changes to the display container to force the dimensions. Something that I have not considered, but will try out.

  6. Hey reading the article above. Really explained well. I implemented it and works just fine. I m facing another problem though. I have an external swf file being viewed from inside my flash file. that swf is a multipage file. How do i write as3 code to print all the pages of tht swf file. Kindly guide me

    1. I would have to look into it, but the tutorial was only designed from within the parent swf. I would suggest putting the print function within your multipage swf. This might not make the app very portable, but I’m not sure how else to do it. I wrote this a few years ago as part of a class assignment. I never went beyond this tutorial.

  7. Nice article. But my question is how to print more than 100 pages without getting time out error.

    1. That I would not be able to tell you. I only did this as part of a class assignment. I can only suggest that it’s possible that your computer is timing out because of the amount of memory that Flash is trying to use while the print job spools. That’s just a best guess.

Comments are closed.