<< BlizzCon 2008 | Home | Blue Tooth Review >>

Flash printing the slow way

Printing a form in these modern times is no miracle, unless you want an exact printout with detailed control from a webpage. In such cases, you must sacrifice a goat and two chickens -- unless you use Flash. CS4's printing engine is both robust and simple, making it the most useful internet tool of our time. Praise aside, after spending almost an entire day working on what routinely is a simple operation, I decided it was probably a good idea to share my experience.



My day started off printing a simple on-screen form. This worked great using the printing API because MovieClip extends Sprite, which is the default parameter needed to add a page to a print job.



var pj:PrintJob = new PrintJob();


pj.start();


pj.addPage( this );   // this refers to the Document object of the executing MovieClip


pj.send();



The page prints, everyone is happy, and all in 4 lines of code. Compiled the code and rolled it out to our new customer site (shameless plug) at <a href='http://www.bluemoosetees.com' target='_blank'>Blue Moose Custom Tees</a>. This let their customers build a t-shirt layout, and their art department would print out the result for production. Simple it seems, until the designs got a bit more complicated.



All of a sudden, users wanted to stack PNG's with alpha transparencies on their designs. Works great until you print out a page with huge black boxes where the graphics overlay each other.  Not very useful for printing.



So we move on to the next step -- PrintJob.addPage has a second parameter that allows you to print the image as either a vector or a bitmap. Vector is the default format, which does not play well with png overlay. Change to a print as a bitmap:



var pjoptions:PrintJobOptions = new PrintJobOptions ();


pjoptions.printAsBitmap = true;


var pj:PrintJob = new PrintJob();


pj.start();



// this refers to the Document object of the executing MovieClip.


// Null is for the print area


// pjoptions allows us to print the png transparency


pj.addPage( this, null, pjoptions );   


pj.send();



Again, success! Of course, by now, our work order is actually larger than a page. Printing all this niceness extends beyond a single page, cropping half of the information. Time to put resize magic in play. Of course, this leaves us some options.



Option a. Resize the actual view area, and print that. Works, but you cant print more than once without re-working lots of code.



Option b. Resize off-screen and print this off-screen image. Now that's a good solution, and a HUGE problem.



NON-WORKING EXAMPLE



    var s:Sprite = new Sprite();



    // Create a BitmapData object base based on the size of the current document


    var bm:BitmapData = new BitmapData(this.width, this.height);



    // THis Matrix is used to resize the off-screen image to 85% of its original height and width. Low tech trial and error


    var mm:Matrix = new Matrix(.85 ,0,0, .85,0,0);



    // draw the document form into our new bitmapdata using the matrix transform


    bm.draw(this, mm);




    // create a new bitmap based on the bitmap data we now have    


    var b:Bitmap = new Bitmap(bm);


    s.addChild(b);



    // print    


    var pj:PrintJob = new PrintJob();



    var pjoptions:PrintJobOptions = new PrintJobOptions ();


    pjoptions.printAsBitmap = true;


                    


    


    pj.start();            


    pj.addPage(s, null, pjoptions);


    pj.send();


    trace(s.height);




This seems simple and all, but it doesn't work. It prints a blank page. Over and over and over -- there is simply nothing there. But have heart, there is a fix. Since we are copying bitmap into our printjob, the transparencies are already preserved. So, to make our document print in a useful way, simply remove the printjob option, and profit!




    var s:Sprite = new Sprite();


    


    // Create a BitmapData object base based on the size of the current document


    var bm:BitmapData = new BitmapData(this.width, this.height);



    // THis Matrix is used to resize the off-screen image to 85% of its original height and width. Low tech trial and error


    var mm:Matrix = new Matrix(.85 ,0,0, .85,0,0);


    bm.draw(this, mm);


    var b:Bitmap = new Bitmap(bm);


    s.addChild(b);


    


    // print    


    var pj:PrintJob = new PrintJob();


    pj.start();            


    pj.addPage(s);


    pj.send();


    trace(s.height);



Of course, whether the blank page is something obvious that every Flash programmer should just understand, or if its a terrible new bug in CS4 is an unanswered question at the moment. Should I ever find the answer, expect great celebrations to follow.




Add a comment Send a TrackBack