When recently playing with Alchemy for AlivePDF I looked at the libjpeg library and thought it would be cool to expose the JPEG decoding capability to ActionScript 3 developers. As some of you may know, the libjpeg can also be used to encode JPEG files in a very optimized way.
So you may wonder, why the hell would I need a JPEG decoder in AS3 ? The Flash Player does it natively and supports it, its not like decoding animated GIFs, or BMP, etc. Well, for my part, I needed a JPEG decoding class for AlivePDF in order to make the addImageStream method work, which basically embed any JPEG file (any dpi) into any page of the PDF created.
When embedding such a file, you need to provide to the PDF reader some informations, like the image dimensions (width, height), its color space, etc in a synchronous way (Loader.loadBytes() is asynchronous). Hopefully the reader takes care of the pixels decoding, you just tell the reader to decode the pixels using the DCTDecode (Descrete Cosine Transform) algorithm and voilĂ .
But now, let's say you create an application which needs to fully decode a JPEG file, retrieve the image dimensions just by parsing the jpeg stream, do any processing on the pixels before sending them to a BitmapData or maybe just simply map them to a corresponding BitmapData object, then this library is for you. This could be done without Alchemy and libjpeg but I guess it would be much slower for big images and I was in an Alchemy mood
So here is what the API looks like :
import org.bytearray.jpeg.decoder.JPEGDecoder; var myDecoder:JPEGDecoder = new JPEGDecoder(); myDecoder.parse(jpegStream); var width:uint = myDecoder.width; var height:uint = myDecoder.height; var colorComponents:uint = myDecoder.colorComponents; var numComponents:uint = myDecoder.numComponents; var pixels:Vector.<uint> = myDecoder.pixels;
The pixels getter returns an ARGB Vector that you can pass to the fast BitmapData.setVector() method.
var width:uint = myDecoder.width; var height:uint = myDecoder.height; var pixels:Vector.<uint> = myDecoder.pixels; var bitmap:BitmapData = new BitmapData ( width, height, false ); bitmap.setVector ( bitmap.rect, pixels );
I will post another version in the following days with more options. Click in the area below to browse for any JPEG file, the pixels are extracted and decompressed in AS3 and sent to a BitmapData object.
Download the sources here.
Comments (15)
This is nice
I looked at JPEG decoding in Flash ages ago when I wanted to load/use CMYK (4 channel) JPEGs in flash.
A custom decoder should also allow more JPEG glitching possibilities…
http://blog.madebypi.co.uk/2009/11/19/jpeglitch/
Hi Mike,
Happy you like it
Talking about CMYK, yes that’s a good idea, I think I will surface also the API to retrieve the JPEG color space, that could be useful.
I will take a look at thise glitching features
Thibault
Nice … maybe the decoder could be used to resize and/or rotate a JPEG without re-compressing it? … do you know how to achieve that?
Hey,
Could this be spread out over multiple frames to not lock the UI?
Flash built in image loading locks when loading and/or decoding.
I guess you can ‘get around’ this by using smaller image sizes, 255×255 should be small enough to not lock too much at 30 FPS for example.
Around 400×400 you take up the entire frame with decoding.
Looked quickly at the JPEG lib but it’s over my head
Assumed the jpeg_finish_decompress() is heavier than jpeg_read_scanlines()..?
Cheers!
Took me a while to realize this is a unique capability (‘what? flash does that’), good for the toolbox.
Next up: synchronous PNG decoding :p
Hi there,
I have been experimenting with loading large jpeg images (larger than 16Mb) into flash using Alchemy code. Image decoding is performed asynchronously, it takes some time for large images. But once again, asynchronous functions can be tuned to be ‘less asynchronous, but faster’. Experiment is available on my page :
http://segfaultlabs.com/blog/post/alchemy-loading-large-jpeg-images/
Hi malczak,
Good one!
I decided to go synchronous for me, cause I needed such a behavior for AlivePDF or other recent projects.
Thibault
Way to go, Thibault!
I’ve always wondered why there are only “JPGEncoder” and “PNGEncoder” in the adobe’s coreas3lib – why no decode classes are included.
Thx to you, know there’s only one more “PNGDecoder” to go
Hey Jloa,
Yep, PNGDecoder would be sweet too. Good idea
Thibault
Hmm, the library doesn’t install. Too bad they probably spent a lot of time making it
I’ve constructed a simple test using your swc and Flash Builder 3. All I did was load a 30k jpeg with URLLoader and hold on to the data. On click of the stage, I decompress the loaded data, create a new Bitmap with it and add it to the stage. On ctrl-click, I clear the stage. Memory just keeps climbing, even after clearing the stage. Using the profiler, there’s thousands of instances of cmodule.jpegdecoder.AlchemyYeild, and thye keep changing, even with no user activity.
I only have one instance of your JPEGDecoder and keep reusing it. Eventually the browser crashes. Any notion as to what’s happening?
Hi Chuck,
I think I know where it comes from. I should have included a dispose() method to free up the buffer used by the image in memory.
I will recompile the SWC and update it and let you know here.
Thanks for noticing this bug
Thibault
Thanks! This is all very interesting. I’m looking into caching the images compressed and reusing them as need be to keep client memory down. I may have some questions going forward.
when i process photo in a row of over 50…i got a error info of “system
is out of memory” in the flex.
help me pls…
Hi there!
This is really great work. I experimented with the alchemy-decoder from segfaultlabs and now I’m juggling with an alchemy-encoder for jpegs.
What I realize is the following: Using the c-commandline-tools decoding some test-JPGs is blazing fast. But using alchemy-crosscompiled libjpeg (mine or yours, Thibault) is considerable slower than the build-in Flash-Loader-stuff. Do you know why?
Trackbacks/Pingbacks (3)
[...] AS3 JPEG Decoder [ by Thibault Imbert ] http://www.bytearray.org/?p=1089 [...]
[...] AS3 JPEG Decoder [ by Thibault Imbert ] [...]
[...] transformation of the movie business, television, print, advertising, marketing and new media. …AS3 JPEG Decoder [ by Thibault Imbert ]AS3 JPEG Decoder [ When recently playing with Alchemy for AlivePDF I looked at the libjpeg library [...]