Speed up JPEG encoding using Alchemy

Few weeks ago Thibault Imbert published an optimized version of Adobes JPGEncoder. And it rocks! However, if you may have very big-size bitmaps it takes too much time to encode images. For example: A bitmap with a size of 2000px x 1500px takes 22 sec. (BTW: Adobes version 30 sec.!!)

Today I came across to a post by Manfred Weber, which points to a discussion at Adobes Alchemy forum. There you will find a great solution published by metalbot for encoding JPEGs using Alchemy. It’s based on a C library for JPEG image compression by IJG and it’s pretty fast (2,7 sec. for 2000 px x 1500px ) !!! Check out the example:

Example

Click the image to see the live example. Feel free to post a comment about your your results!

Screen shot

Download Full Source

I have changed the original C code a little bit for manipulating the quality of an encoded image as well. It’s just one line added to “as3_jpeg_wrapper.gg” (line 78) jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); Therefore the “as3_jpeg_wrapper.swc” located within the *.zip is recompiled for using this feature in your Flex project via as3_jpeg_wrapper.write_jpeg_file(baSource, WIDTH, HEIGHT, 3, 2, quality);

Full source of the Flex based example above: AlchemyJPEGEncoderFlexExample.zip (Downloads: 4207)

BTW: You will find the original source of all C based classes published by metalbot here.

Tips

I struggled around to set up Alchemy and to recompile the IJG library and the “as3_jpeg_wrapper.swc”. To avoid this, here are some tips:

  • Instruction for set up Alchemy by Lee Felarca (zeropointnine). Best instruction I’ve found so far for set up Alchemy.
  • Recompiling the SWC of metalbot’s source following its “README.txt” and using its “Makefile” failed: To avoid this issue, after compiling the C library of jpegsrc you have to move the following files to $ALCHEMY_HOME/jpeg/ as well: “jconfig.h”, “jmorecfg.h” and “jpeglib.h”. Check out the comment by notnick here

[UPDATE 06/22/09] There is another great test for encoding images using Alchemy by Mateusz Malczak, which includes an asynchrounous example as well: Alchemy – asynchronous jpeg encoding Thanks to xoestudio for pointing to this via twitter! [UPDATE]

Have fun ;)

-Jens

Alchemy | Flash | Flex | Open Source

 

27 Comments

  • Mario Junior says:

    LOL! Very nice, congratulations!

  • Simon Bailey says:

    Nice example and cool as heck results, good work Jens!

  • Congratulations.

    Alchemy does some data manipulation much faster than standard AS3. Here is some comparison incrementing 1000000 numbers at a time using a vector, array, and bytearray with alchemy (alchemy wins):
    http://arcanearcade.blogspot.com/2009/03/alchemy-bytearray-faster-than-vectors.html

  • Nick says:

    Very cool. Next step if this hasn’t already been done — get the jpeg encoder to work with EXIF data.

  • Mete says:

    Is that picture from Karpasia?

  • sectore says:

    @Mete: I took this picture in an area called “Supramonte”. It’s a very beautiful mountain area on Sardinia / Italy ;)

    -Jens

  • I have used both the alchemy swcs for adding image byteArrays into pdf using alivepdf. When I don’t use the position property for the byteArray I get a black image and if I set the value to zero then it appears skewed. When I change the value to some positive integer the skew appears in different angle. Need help!!

  • Jason says:

    First, thank you for this great post. I have been able to get alchemy up and running successfully.

    I use a function ‘handleLoadPicture’ (see below) in a drag and drop scenario to add pictures to my AIR application. When I start my AIR application, I am always successful on the first drag and drop. I always get the following message on my second attempt at a drag and drop during my session:

    RangeError: Error #1506: The specified range is invalid.
    at cmodule.as3_jpeg_wrapper::FSM_imalloc$/start()
    at cmodule.as3_jpeg_wrapper::FSM_pubrealloc/work()
    at ()
    at ()

    private function handleLoadPicture(event:Event):void {

    var loader:Loader = Loader(event.target.loader);

    var image:Bitmap = Bitmap(loader.content);

    var init:CLibInit = new CLibInit;

    var as3_jpeg_wrapper:Object = init.init();

    var ba:ByteArray = image.bitmapData.clone().getPixels(image.bitmapData.rect);

    var baout:ByteArray = as3_jpeg_wrapper.write_jpeg_file(ba, image.bitmapData.width, image.bitmapData.height, 3, 2, 100);

    picture.source = baout;
    }

    Any help would be greatly appreciated. Thank you!

  • danno says:

    is there a version that will work with flash cs3/cs4 instead of just flex?

    thanks!

    rocksteady,
    danno~

  • Sebastian Chiariello says:

    What are the parameters 3 and 2 on write_jpeg_file method?

  • Sebastian Chiariello says:

    Well… does’t work if i changed so… dont care.

    Have another question if any can help i will appreciate:
    I have a image that i rotate with Matrix method, i want to save the rotated image, but it just save the original image. I need also to apply some filters to this image so, why does’t save the matrix transform
    update?

    Thanks in advance

    PS: fix the math question… i think U have a problem in math hehe (at least on firefox isnt work)

  • Jason says:

    HI,I use your as3_jpeg_wrapper.swc to compress jpeg,because of the high cpu the whole IE dead,and it can’t do anything,I think if I can send event to actionscript3.0 in swc like the progressBar in actionscript3.0,so I can know the progress like the actionscript3,what’s more,the most import is how i can solve the IE death,look forward you reply.

  • Jason says:

    Hi,I compile your c source,but there are some questions and I can’t sucess,Can you give me some suggestions,Look forward your reply,Thanks!!

  • dada says:

    hello.

    I had this error : RangeError: Error #1506: The specified range is invalid.

    It stopped occuring when I put as3_jpeg_wrapper.swc initialization code into the static method that is fired only once. Maybe it could help.

  • The alchemy JPEG is really great! I’m using it in Flash so it’s took me a while to get it working, but when you finally get there, it works like a charm.

    A little tip:
    I found that it was very easy to get the progress of the encoding when using the asynchronous encoder. Just set up a function that monitors baSource.position/baSource.length via setInterval or similar while encoding.

  • Kikolin says:

    Hi everyone,
    I’m trying to make this work on flash CS4 but I might be doing something wrong.

    Fist of all I have included the swc as an external library in as3 advanced configuration. I have an image in the library with a class name Test and in frame 1 I have this code:

    ———————————–
    //Use an image from library
    var bitmap:Bitmap = new Bitmap();
    var mytest:Test=new Test(200,200);
    bitmap.bitmapData=mytest;

    //And the Alchemy stuff
    import cmodule.as3_jpeg_wrapper.CLibInit;
    var as3_jpeg_wrapper:Object;
    //
    var quality:int=100;
    var bitmapData:BitmapData;
    var WIDTH:int=100;
    var HEIGHT:int=100;
    var imgAlchemy:Bitmap=new Bitmap();
    //
    // init alchemy library
    var loader:CLibInit=new CLibInit ;
    as3_jpeg_wrapper=loader.init();
    // get image
    bitmapData=bitmap.bitmapData;
    //
    function startAlchemy():void {
    var baSource:ByteArray=bitmapData.clone().getPixels(new Rectangle(0,0,WIDTH,HEIGHT));
    var baAlchmey:ByteArray=as3_jpeg_wrapper.write_jpeg_file(baSource,WIDTH,HEIGHT,3,2,quality);
    imgAlchemy.bitmapData.setPixels(new Rectangle(0,0,WIDTH,HEIGHT), baAlchmey);
    addChild(imgAlchemy);
    }
    startAlchemy();
    —————————————————–
    And i get this mesage from flash:

    VerifyError: Error #1014: Class cmodule.as3_jpeg_wrapper::CLibInit could not be found.

    at global$init()

    Any ideas? Thanks in advance.

  • I have just put up a tutorial/guide on how to use the Alchemy JPEG encoder in Flash. It’s also an example on how to use a progressbar to monitor the encoding. Check out http://last.instinct.se/graphics-and-effects/using-the-fast-asynchronous-alchemy-jpeg-encoder-in-flash/640

  • Kikolin says:

    Klas, Great tutorial and work.
    Thank you very much!!!

 

Leave a comment

*