Jun 2, 200821

ActionScript 3 Jpeg Encoder Revealed: Saving Images from Flash

Some amazing things can be done with images in ActionScript 3. One of these is the ability to encode a display object as a jpeg, and thanks to the JPEG Encoder included in the AS3 Core Library, doing this is actually quite simple. In this article, I will show you how to create a flash file that encodes a movieclip as a jpeg and allows the user to download it to their own computer.

To give you an idea of how this can be used, try out the sketch pad below:

First Things First

Before we get started, make sure to grab the ActionScript 3 Core Library. The Core Library contains several classes and utilities that make it easy to do things such as MD5 hashing, date formatting, and image encoding to name a few. Once you have the library, just drop it into your classes folder and you are ready to go. Now we can import the JPGEncoder.


import com.adobe.images.JPGEncoder;

Encoding the MovieClip

In this example, we are going to assume that our MovieClip of interest is named sketch_mc. In order to make use of the JPEGEncoder, our MovieClip needs to become a bitmap. To do this, we are going to use the BitmapData class. The contructor for this class requires two arguments: width and height. Since we want our jpeg to be the same size as sketch_mc, we use it’s width and height properties. Then by using sketch_mc as an argument, the draw method draws our MovieClip on to the bitmap.


import com.adobe.images.JPGEncoder;

var jpgSource:BitmapData = new BitmapData (sketch_mc.width, sketch_mc.height);
jpgSource.draw(sketch_mc);

Now that sketch_mc is in bitmap form, we can use the JPGEncoder. When creating a new instance of this class, you can set the level of compression by passing in a number from 1 - 100. Then to create our jpeg, we call the encode method and use our BitmapData instance as the argument. The encode method returns the jpeg in the form of a ByteArray, which is simply an AS3 class that makes working with binary data a little easier.


import com.adobe.images.JPGEncoder;

var jpgSource:BitmapData = new BitmapData (sketch_mc.width, sketch_mc.height);
jpgSource.draw(sketch_mc);

var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgStream:ByteArray = jpgEncoder.encode(jpgSource);

From the Flash Player to the Hard Drive

ActionScript 3 has done all the work neccessary to turn our MovieClip into a jpeg, but it needs a little help in making it available to download. To make this happen, we will need to post our ByteArray to a server side script using the URLRequest class. Since we are posting binary data, we must set the content-type to “application/octet-stream”. It is also important to note that the file being downloaded will need a name, so we pass that to our server side script as a query string.


import com.adobe.images.JPGEncoder;

var jpgSource:BitmapData = new BitmapData (sketch_mc.width, sketch_mc.height);
jpgSource.draw(sketch_mc);

var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgStream:ByteArray = jpgEncoder.encode(jpgSource);

var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var jpgURLRequest:URLRequest = new URLRequest("jpg_encoder_download.php?name=sketch.jpg");
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = jpgStream;
navigateToURL(jpgURLRequest, "_blank");

Below is the php script to where we are posting our jpeg. I chose to use php for this example, but any server side script will do.


if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
	// get bytearray
	$jpg = $GLOBALS["HTTP_RAW_POST_DATA"];

	// add headers for download dialog-box
	header('Content-Type: image/jpeg');
	header("Content-Disposition: attachment; filename=".$_GET['name']);
	echo $jpg;
}

Note: I originally wrote this article for HenryJones.us. Since it was incredibly useful to a lot of people, I decided to make it available to all of the Design Reviver readers.

Download Sample Code

21 Comments

  • dZine
    Jun 3, 2008

    Great tutorial! I need something like this for an upcoming project. It’s like you read my mind :)

  • k64
    Jun 3, 2008

    Does not work unless popup is enabled. :(

  • Fernando Lins
    Jun 4, 2008

    There’s something wrong with the JPEG generated. This is how it appears to me on Mac OS X’s Preview.app : http://dznr.org/h9al

  • Angel Romero
    Jun 5, 2008

    Nice tutorial! Short and straight to the point.

  • Josh Read
    Jun 5, 2008

    Thanks again for all of your tutorials. I love this site! Seriously, I’ve learned a lot by reading it and I’m now pointing everyone from my company’s blog to it as well: http://www.ainsworthstudio.com - the company blog is at http://www.tacomagroups.com

  • Henry
    Jun 5, 2008

    Fernando Lins,
    It works fine for me on a Mac. Does anyone else experience this?

    Josh Read,
    You’re welcome. I am glad you are finding the information here useful.

  • jarav
    Jun 10, 2008

    Does not work with Flash Player 10 beta on Ubuntu Hardy. The downloaded file is just 4 bytes.

  • Stephen Braitsch
    Jun 19, 2008

    I wrote a similar tute that also allows for png creation using a similar class from the Adobe Core Lib.

    http://www.quietless.com/kitchen/upload-bitmapdata-snapshot-to-server-in-as3

  • Rob Frau
    Jun 20, 2008

    Hi. It’s a great source, but i use Win2003Server, is there a similar solution for asp or asp.net script file?

    Thanx

  • Marshall
    Jul 2, 2008

    The jpg doesn’t show up on Leopard for me. It appears as the question mark. Fernando Lins might have been referring to this same problem. I tried Safari and Firefox.
    Thank you for any help

  • jarav
    Jul 4, 2008

    Works now on Ubuntu Hardy with Flash player 10 beta 2.

  • cy
    Jul 6, 2008

    I’m trying to make this save back to my server (ie save the users’ art. Any ideas on how to make this happen? Is this even possible?

    Thanks for the tutorial and all your help!

  • Henry
    Jul 7, 2008

    @cy - I’ve added a file to the example download that should help you save the image to your server.

  • PatStars
    Jul 23, 2008

    Very cool. Works nice and smooth.

    Is it also possible to use a brush instead of just the basic line? How would be the best way to do this?

    Thanks.

  • Adam
    Aug 11, 2008

    Hello, this is a script I would like to use on my website, however i am not sure where to put the corelib on my pc. if you could explain that a little more that would be great. everywhere i have tried to place still gives me errors.

    Thanks

  • Jayden Lawson
    Aug 11, 2008

    Awesome. Is there anything similar for AS2?

  • Sushil
    Aug 13, 2008

    I taken the help of above code to design an sign pad. But the problem is its bit itchy and not smooth as the one http://dev.adamtstein.com/signpad/

    is there anyway to increase the smoothness of above sketch pad.

    Thanks in advance!!!!

  • Henry
    Aug 13, 2008

    @Sushil - If the one in the link you provided is yours, it looks pretty smooth to me. However, you could try increasing the frame rate of you movie.

  • Sushil
    Aug 13, 2008

    Thanks!!!But I tried even that. but its not working as smooth as the one I mentioned. Is there any other way of increasing the smoothness.

  • Ian
    Aug 26, 2008

    Hi Henry,

    I’ve tried downloading your sample code, compiled it using flash CS3 with the com.adobe.images.JPGEncoder.

    The flash works fine, but when I try “Download to Sketch”, it opens up a new window and ask if I want to save the jpg_encoder_download.php file. Did I miss out something?

    Thanks for the help

  • CH
    Aug 27, 2008

    Can anyone give an example of how to load a bitmap as the canvas_mc background, instead of the white fill? I can’t get this to work without hiding the drawing.

Leave a Comment