Using the AS3 Jpeg Encoder
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;
}
That’s it. It really doesn’t get much easier than that. Of course, to make your code more reusable, you probably want to wrap it in a function or create a custom class.
50 Comments
Leave a commentThanks for the article. Exactly what i’m looking for.
Can you post the complete code or files as well?
I’m having a few issues getting the php file to bounce back the image.
thanks again!
Daniel - Glad the article was a help. I will try to get the code posted sometime today.
Thanks.But i downloaded your sample code,it cannot get work.
It always echo :An error occured.
in my browser bar :http://localhost/jpgdown/jpg_encoder_download.php?name=sketch.jpg? %EF%A3%B5??,,0,0,,
But this “?%EF%A3%B5??,,0,0,,” ,why?
My php version 5.2.3
My os: xp sp2 home edtion (I ‘m from China).
Pls help me.
xcf007 - I am not sure why the “%EF%A3%B5??,,0,0,,” is in there. I will have to look into that.
Perfect! Thank You. Worked on the first try.
Do you by chance have a PHP script that would save this file to a folder on the server?
Much Thanks!
I’m was having the same issue as xcf007, it makes a request but adds those extra characters. I figured it out though: when testing the .swf from the local filesystem it adds junk to url, I don’t know enough to sound educated as to why, other than some kind of security “feature.” The solution is to put the .swf in you webserver directory so it can run from the same security zone as it is making the request to. Now it works!
Sweet tutorial, but I second the request for the complete demo, although now that I’ve overcome that hurdle it’s not as necessary.
Daniel,
Thanks for pointing that out. I assumed xcf007 was running the file on a web server, but I guess he wasn’t.
hi. Havin problems getting it workin in firefox. works fine in ie but no ff!
Simon,
What exactly is it doing in Firefox?
Hi Henry, thanks for the article.. had a thought, how to have overlaying image or text on the pad, which would be included in the sketch snapshot? Cheers,
vincent,
Anything in your Movieclip would be included in the ecoded image. So, it would be simple to add text or an image.
Hi Henry,
That will save my life! Thanks , but I have a small problem.
Everytime while publishing your movie in Flash I get the error:
1120: Access of undefined property myMovieClip.
Do you know what I am doing wrong?
Can anyone help me with the script that should be used for the “download your sketch” button?
I’m the same as Keith, would it be possible to have the above example (sketch pad) with the code. I’m finding it hard to make the transition from AS2 to AS3 and need help!! thanks!
I’ve added the source for the sketch example to the sample code download.
Henry,
thank you very much!
Henry,
I owe you a BIG thanks for this jpeg encoder
Maybe you should update the title of your post adding “how to export jpeg with flash” for search engine optimization because I would had never find you if someone hadn’t give me the url of this tutorial on a forum.
Many thanks anyway
hi, this is what actually i’m searching for!
million thanks to u. u saved me.
Thanks heaps for the article. Exactly what I needed.
Anyone know how to do the same with multipart encoding though?
This is great, very simple but not dumbed down, I’m actually using a modified version of it to save to the server, but I’m getting a weird artifact . . . it keeps putting a white strip on the top of the image, I really have know idea what it is but I think it’s something server side, like maybe it’s getting the other parameters I am posting with it confused as part of the data . . . any help would be great
Hello!
Thank you so much for sharing this example.
I have one question: does anyone know what are the size limitations for the image that is to be saved? the maximum Width X Height.
Thanks,
Marcel
Hi, many thanks for that post, just so great !
I wonder if it’s posssible to use it on a local area, wthout using php on a server side. I explain, I’ve exported this great .fla into an .exe and i Want to save directly the jpeg file from this exe to my hard drive, without passing on a web server. Is that possible?
Thanks for the help
@psykoleo: if you use AIR you can interface with the user’s file system directly.
Thank you Michael, I’ve never used AIR but I’ll try if you say it will answer my need. Now everything’s fine trhough a web server, but I want to use it offline without php if possible… so let’s go for some AIR !
Hi, Thanks for this such Great Post !
As I’m more a graphic designer than a programer, I have to admit I’m quite lost for my purpose, specially in AS3.
Anyoe could help me for this please? Thanks in advance.
I want to have a 180dpi image in background (for printing purpose) with an overlay editable TextArea, then save the whole thing into a jpg.
I’ve tried to do this on my own, here is the file:
http://refonte.dedikam.com/telechargement.php?clef=9c0198494c4cc6e1948a1cf21250c5f2
But at the end, I’ve just have a blank image at the right size but not resolution (72dpi instead of 180dpi), without my backgound and my text.
Many thanks in advance and thanks again Henry for this great post !
All the best,
Romain (from France)
This will be a great tool… I’m just stuck at step 1… where do I find the classes folder into which I place the Core Library? When I do a Windows Explorer search on “classes” there are a number of them in the Adobe realm.
wow! you just possibly saved our butts! We had to do exactly this! But we’re having trouble with the library. I copied the entire corelib file to the first run/classess folder. Is that all we have to do? Then we can just execute the sketch.fla file & it should work?
romain,
I will take a look at your file and see if I can spot the problem.
Ned and Maggie,
Here is some info about setting up a class path:
About Setting Up a Class Path
If you are still having problems, just let me know.
wow! you’re great. Thank u so much 4 the speedy answer
I think I’ve managed to import the library. I can now draw the way you do, but I can’t export the image. It opens up a browser & then does nothing. You think it’s still the classpath I need to worry about or could it be something else I’m missing?
Dear Henry, thanks for your answer.
I’ve finally found half of my problem for the drawing scene matter.
I’ve written jpgSource.draw(m);
instead of jpgSource.draw(this);
No it’s work… except the fact that the final JPG I’m saving is still in 72dpi instead of the 180 dpi I need for printing purpose. (The native .tiff file I’m putting into the flash library is at 180dpi).
Thanks again.
wow, romain. You got it to save an image at all? I really really wanna make this work. Did you change anything to make it work? Thanks a lot
Maggie,
If you are not getting errors when you publish your file, then the library is being imported correctly. Is your server running php?
Maggie, I’ve just erased all I didn’t need, and replace the:
jpgSource.draw(m);
by jpgSource.draw(this);
in order to have what I’m writtng within the text area included in the saving jpg file.. No success for the moment for the mater of resolution.
[...] to the ByteArray and post it. For more detailed information on how to put all the pieces together, Henry Jones has a really thorough post of compressing JPEG data and pinging it off a server to force an image [...]
I’ve noticed that the library also supports the export of PNG files, but will it export them with transparency?
Nevermind. I figured it out. All you have to do is have the BitmapData and beginFill maintain the transparency and switch everything over to the PNGEncoder. That’s it.
[...] http://henryjones.us/articles/using-the-as3-jpeg-encoder [...]
I’ve been trying to use the php script however, I constantly get the error message ‘An error occurred’. I think it has something to do with HTTP_RAW_POST_DATA.
I got this code to work and save the the user’s desktop. Now I’m trying to save a copy to my server. Does anyone know how this would work? It seems that if I try to display the jpg in the PHP page, all I get is the code for the jpg. Do I need to decode it first or is there something I’m missing.
Hi !
So great article. I have the same problem of romain. I’m looking for a solution to encode a JPG with 300dpi instead of 72 by default.
Someone know how do it ?
thanks
Thomas (from france too
Hi,
First of, thanks for the article Henry, its great to find someone actually made this because im trying to do something related. However like the other guy said, maybe you should do something about your SEO because it took me hours to find this
Besides that, im having trouble getting it to work, this must be my limited knowledge of both flash actionscript and php. Im more at home with java jsp etc.
My problem is this, after i get the drawing screen working and i press the save to disk button it opens a empty internet page and stops there. What i did was just download your example put it on my test server. After putting the libraries in the correct location and adding the classpath i installed php on my server. Then i opened your fla file and pressed ctr enter. This all worked, but when i then try to save it, i get the above problem.
Anything about php that needs special atention to get this working? Or should the swf be embedded in a html or something to work?
Jasper
Hi,
As is often the case, you ask something and then its fixed
Got the problem, i needed to put the php in a dir then run the swf from a browser out of that directory. My bad
Gr, Jasper
Hey, I’m not a big php guy. Anyone know how to change the php script so that it save the .jpg onto your server instead of bouncing it back to be downloaded?
thx,
Dan
This is brilliant!
And wonderfully executed for this purpose as well as cleanly extensible. Thank you. I will be extending this for another cool purpose that will include answering your php server question above, and will link to a post on my own site once we develop it.
Thanks again!!
~devPrez
I’ve managed to get it to work when I test it on my localhost, but for some reason when I load the files to my server it does not do anything. I am using flex builder 3 and this is pretty much the last piece of the puzzle I need to get this project out.
This works like an absolute champ, thanks! The description and follow up on the comments answered all my questions. Of all the parts of my project, this one turned out to be the easiest.
Thanks for this post, it saved me alot of time.
Does anyone know how to modify the php to save the file in the server?
Thanks!
Here you can find how to store the file in your server:
http://blog.joa-ebert.com/2006/05/01/save-bytearray-to-file-with-php/
I’m trying to create source mc in background and then send it to this function but I receive just empty (white) jpg’s. I there any solution for that? In other words - is there any solution which could allow me to create mc without making them visible, adding them to any container.
I’m working on a soda can caption editor, where user puts gfx on a small sketch pad, then a second function builds a big (ca 2000px 300 dpi) jpg.
By the way, I used this snippet few times and it works really great, makes life much easier:)
Leave a Comment