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: 1567)

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

25 Responses to “Speed up JPEG encoding using Alchemy”

  1. Mario Junior Says:

    LOL! Very nice, congratulations!

  2. ????tv?? » Actionscript 3, JPEG ???????? Says:

    [...] Speed up JPEG encoding using Alchemy ???? Adobe Forum ?????? JPEG ???????????????????????? ??????????bytearray.org ? FP10 ???????? JPEGEncoder ?????????????? ???????????? ???????????????… [...]

  3. Simon Bailey Says:

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

  4. Robert Stehwien Says:

    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

  5. Nick Says:

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

  6. Mete Says:

    Is that picture from Karpasia?

  7. sectore Says:

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

    -Jens

  8. Load, modify and save local images with Flash Player 10 | Floorplanner Tech Blog Says:

    [...] Update 3: You can now also use Alchemy for the encoding. It’s much, much faster then the other options! See this post from Jens Krause: Speed up JPEG encoding using Alchemy [...]

  9. Susrut Mishra Says:

    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!!

  10. 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!

  11. danno Says:

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

    thanks!

    rocksteady,
    danno~

  12. Sebastian Chiariello Says:

    What are the parameters 3 and 2 on write_jpeg_file method?

  13. 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)

  14. ActionScript 3 encoding JPEG at Jozef Chú?ka's blog Says:

    [...] Speed up JPEG encoding using Alchemy [...]

  15. 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.

  16. 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!!

  17. 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.

  18. Flash Jpeg Encodierung mit Alchemy | Augmented World Says:

    [...] Ich arbeite zur Zeit an einem Projekt bei dem Bilddaten in einer Flashapplikation bearbeitet und danach auf einen Server übertragen werden. Ein großes Problem bestand bis jetzt darin die Bitmapdaten nach Bearbeitung in JPEG zu encodieren. Dieser Vorgang ist sehr rechenintensiv und brachte die Applikation für einen kurzen Moment zum einfrieren.  Durch Zufall bin ich über einen Blogeintrag von Jens Krause gestolpert. <Link> [...]

  19. Klas Lundberg Says:

    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.

  20. 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.

  21. Load, modify and save local images with Flash Player 10 « TMHs Web Tips Says:

    [...] Update 3: You can now also use Alchemy for the encoding. It’s much, much faster then the other options! See this post from Jens Krause: Speed up JPEG encoding using Alchemy [...]

  22. Klas Lundberg Says:

    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

  23. Kikolin Says:

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

  24. 360cities.net panorama Downloader | Wersling's Blog Says:

    [...] ??Jens Krause??JPEG?????????????? [...]

  25. Passing webcam data into WebGL via Flash - peter nitsch.net Says:

    [...] when done in haXe or Alchemy. In this case, I'm using both. The JPEG compression is performed by metalbot's Alchemy JPEG encoder, while the Base64 encoding is handled by Bloodhound's haXe crypto library. ExternalInferface passes [...]

Leave a Reply

Follow sectore on Twitter