Speed up JPEG encoding using Alchemy
June 21st, 2009
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!
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



June 21st, 2009 at 8:31 pm
LOL! Very nice, congratulations!
June 21st, 2009 at 8:41 pm
[...] Speed up JPEG encoding using Alchemy ???? Adobe Forum ?????? JPEG ???????????????????????? ??????????bytearray.org ? FP10 ???????? JPEGEncoder ?????????????? ???????????? ???????????????… [...]
June 21st, 2009 at 9:16 pm
Nice example and cool as heck results, good work Jens!
June 21st, 2009 at 9:28 pm
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
June 21st, 2009 at 10:24 pm
Very cool. Next step if this hasn’t already been done — get the jpeg encoder to work with EXIF data.
June 22nd, 2009 at 1:09 am
Is that picture from Karpasia?
June 22nd, 2009 at 8:08 am
@Mete: I took this picture in an area called “Supramonte”. It’s a very beautiful mountain area on Sardinia / Italy
-Jens
June 22nd, 2009 at 10:04 am
[...] 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 [...]
July 16th, 2009 at 11:25 pm
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!!
July 20th, 2009 at 4:18 pm
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!
July 24th, 2009 at 1:43 am
is there a version that will work with flash cs3/cs4 instead of just flex?
thanks!
rocksteady,
danno~
September 17th, 2009 at 6:28 pm
What are the parameters 3 and 2 on write_jpeg_file method?
September 17th, 2009 at 6:45 pm
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)
October 9th, 2009 at 1:09 pm
[...] Speed up JPEG encoding using Alchemy [...]
December 8th, 2009 at 3:13 am
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.
December 11th, 2009 at 6:16 am
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!!
February 7th, 2010 at 11:19 am
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.
February 22nd, 2010 at 1:50 pm
[...] 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> [...]
March 14th, 2010 at 9:20 pm
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.
April 6th, 2010 at 9:27 am
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.
April 13th, 2010 at 9:44 am
[...] 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 [...]
April 14th, 2010 at 1:14 am
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
April 15th, 2010 at 11:46 am
Klas, Great tutorial and work.
Thank you very much!!!
July 5th, 2010 at 4:25 am
[...] ??Jens Krause??JPEG?????????????? [...]
July 16th, 2010 at 9:46 pm
[...] 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 [...]