Monday, October 24, 2005

More fun with image formats in AS3

So I did post a PNG encoder done in AS3. Well, when you look at the code you realize it's still rather simple. So you might not believe that AS3 is able to something 'real'. This weekend I was looking for some good sample code to show off AS3 and after typing in "JPEG encoder source code" into our favorite search engine, I got a link to this. Well, this code looked rather non portable to something like Java or JavaScript but I took the challenge and made it happen. It really works!

It's certainly not the highest performance possible, but encoding a 1024x768 image in about 6 seconds in not too shabby for an initial implementation, don't you think so? Try to do this in AS2 and you will certainly fail. ;-)

The funny part here is that I was hunting for an artifact bug for about 4 hours, not understanding why I got color banding when decoding the JPEG I had encoded. Little did I get that I had used Remote Desktop to log into my office machine to code this and missed that it forces 16bit depth for some reason although I had selected 24bit. Talking about overfocus, I was really sure it was a bug in my code :-) Usually Flash detects the native screen depth and will try display content decently using ordered dithering. But in this case the Flash Player was advised by the OS to use a 32bit bitmap resulting in the 'bug' I was seeing. There was some ugly color banding since Windows XP does not apply any dithering in 16bit display mode but just simple clamping.

Anyway, I hope you may find this useful somehow... To use it, you need to instantiate it using a quality parameter which is the standard 1...100 value for JPEG compression:

var jpegEnc:JPEGEncoder(75); // argument
// is the quality parameter
var jpegDat:ByteArray = jpegEnc.encode(myBitmapData);

The input parameter for JPEGEncoder.encode() is a BitmapData object. Similarly to the PNG encoder the resulting ByteArray object will contain the encoded JPEG file which you can send to your server.

41 Comments:

Anonymous Daniel said...

Very cool! thanks for sharing.

Monday, October 24, 2005 4:15:00 AM  
Anonymous Anonymous said...

truly awesome, what about sound and video? could you take import from a mic and webcam and encode it to say mpeg4 or something? I realise the encoder wouldn't be realtime, but it would be cool to create a simple NLE in flash and be able to save out the creation.

With byte level control can you make pretty much any filetype? Also how about a RAW image decoder? Can flash process any images accessed via the browse before uploading them or does it always have to upload them, download them, process them, upload them, process them on the server, then offer the download of the new format? Coz that really pretty much sucks.

Monday, October 24, 2005 5:39:00 AM  
Anonymous Anonymous said...

Hi, ok i dont feel that stupid, cos i guess were all newbies now, but how do i get this code to work.

I copied and pasted it as a flexbuilder actionscript project and got
"The target file does not have an externally visible definition."

how do i set it up?

Monday, October 24, 2005 10:43:00 AM  
Blogger KiggD said...

Unbelievable! I'm just stunned at what one can do with images with AS3.

-Danny

Thursday, October 27, 2005 12:59:00 PM  
Anonymous Anonymous said...

cool example.
anyway to DECODE from base 64 into a ByteArray?
ie: stream a a binhex xml jpwg then decode it into a PNG or JPEG and display in an mx:Image tag?

Sunday, October 30, 2005 11:59:00 AM  
Anonymous Anonymous said...

If we generate a JPG/PNG like this, can we offer somehow to let the user to save it to disk?

Monday, October 31, 2005 11:57:00 PM  
Anonymous Anonymous said...

Can't figure out how to run this great .as script. Do I create a as project and reference this somehow, or do I create a flex project and refernec this from mxml....... and how.

Anymore info would be greatly appreciated as I'd love to give this a try. thanks

Friday, November 04, 2005 9:33:00 AM  
Anonymous Anonymous said...

HI TINIC

Would appreciate if you could get in touch

SU

Wednesday, November 16, 2005 1:32:00 PM  
Anonymous Anonymous said...

After many hours, I totally got it working, and with a save locally or on server...........AWESOME!!!

Wednesday, November 23, 2005 5:01:00 PM  
Anonymous Anonymous said...

Usually Flash detects the native screen depth and will try display content decently using ordered dithering. But in this case the Flash Player was advised by the OS to use a 32bit bitmap resulting in the 'bug' I was seeing. There was some ugly color banding since Windows XP does not apply any dithering in 16bit display mode but just simple clamping.

No, i've seen some seriously messed up things in 16 bit color mode and bitmap caching, matching colors and seeing the background and its bounding box slide when displaying is a real mess.

other exciting screwups in 16 bit color mode - certain Flash Projectors spinning up to 100% cpu and eating 50meg of memory/second - looks like the loadMovie forgets its in 16 bit mode and messes up bigtime behind the scenes

Tuesday, December 13, 2005 4:51:00 PM  
Anonymous Anonymous said...

Can somebody post a link to a downloadable working version of this script?
I just can't get it to work.

Thanks!

Thursday, June 29, 2006 2:58:00 PM  
Anonymous Anonymous said...

Someone, anyone PLEASE HELP!

I an usg this JPEGEncoder in Flex 2 Release. It works great if I just load a bitmap and encode it right away. However, if I rotate the image, and draw it onto a new bitmap, then encode it. The jpeg file is corrupt :S.

Heres what I am doing:

//grab the original and clone it
var bmp:Bitmap = new Bitmap(tempImage.bitmapData.clone());

//apply the transformations
bmp.transform.matrix = tm.getTransformationMatrix();

//create an empty bitmap that is the new width and height
//of the rotated bitmap and draw the rotated bitmap into it
var nbmp:BitmapData = new BitmapData(bmp.width, bmp.height);
nbmp.draw(bmp.bitmapData, bmp.transform.matrix);

If I encode nbmp.bitmapData the JPEG is corrupt.. Whats going on??

Thanks,

Matt

Thursday, July 20, 2006 8:57:00 PM  
Anonymous Anonymous said...

Anyone seen a TIFF Image decoder for Flash 9? I am trying to display a TIFF CCITT-Group 4 file in a flash application

Monday, September 25, 2006 8:04:00 PM  
Anonymous Anonymous said...

Hi there, this is great. Im hoping to use this with the BitmapData.draw() functionality to get a screen shot of a movie clip that you can drag and drop stuff on. Im very comfy with AS 2.0, but so many things have changed with 3.0. Can you offer any advice on finding a way to play catch up? And also, have you heard of anyone using anything other than php to post images to a server?

Tuesday, January 30, 2007 10:32:00 AM  
Blogger Sander Kruger said...

Hi, I modified the code so that it doesn't block the Flash Player (which can be inconvenient for bigger images). Find the mod here:
NON-blocking JPEGEncoder

Tuesday, February 13, 2007 1:52:00 PM  
Anonymous sarah said...

Awesome that you've figured this out, but is this valid as3? There's a lot of return types of Void instead of void, and a few other issues.

Tuesday, March 13, 2007 1:51:00 PM  
Blogger Dave said...

Thanks for this, really great.

for those needing to get the data saved to their server in ASP;-

Option Explicit
dim my_filename, StreamRequest, data

my_filename = replace(request.querystring("name"), "'", "\'")
' get the data from the flash -> octet-stream
data = Request.BinaryRead(Request.TotalBytes)

Set StreamRequest = Server.CreateObject("ADODB.Stream")
StreamRequest.Type = 1 'adTypeBinary
StreamRequest.Open
StreamRequest.Write(data)
StreamRequest.SaveToFile [yourpath] & my_filename, 2 'overwrite exisiting

StreamRequest.Close
Set StreamRequest = Nothing

where [yourpath] points at a folder on the server that can be written to.

Hope that helps.

Wednesday, April 25, 2007 8:17:00 AM  
Anonymous Justin said...

I found out that adobe flash CS3 professional doesn't work with your JPEGEncoder class because it doesn't allow two classes (JPEGEncoder and BitString) in the same package file. How can fix this problem?

Thursday, April 26, 2007 4:08:00 PM  
Blogger Nishant said...

Really need help here.

How does ByteArray object translate to Java. I need to save the encoded jpeg on server using java. I'm sending the ByteArray to servlet using a remoting call. Please point me to working samples if any. Thanks in advance.

Saturday, April 28, 2007 5:18:00 AM  
Blogger Ade said...

hi

does anyone know how i can use this package via flash cs3?

regards

ade

Monday, May 21, 2007 8:19:00 AM  
Blogger elffikk said...

To send an encoded image to server you can use base64 format. There are Base64Encoder and Base64Decoder to convert ByteArray base64 to string and viceversa.

Saturday, June 09, 2007 1:11:00 AM  
Anonymous Anonymous said...

How can we send the "bytearray" using ExternalInterface API ?

what i want to do is, basically, save a jpeg from flash using c# in a windows application.

Saturday, June 09, 2007 12:47:00 PM  
Anonymous Anonymous said...

Hi,
is it possible to display an image embedded off a server in the img tag inline without the img being displayed on a seperate line break.

Any help much appreciated

Monday, June 18, 2007 2:00:00 PM  
Anonymous Anonymous said...

You can use the encoding to base64 method to send the byteArray by externalInterface. there is a class here: http://www.dynamicflash.com/goodies/base64

in a C# app you can easily convert base64 to byteArray again.

Thursday, July 12, 2007 5:56:00 AM  
Anonymous Özel Ders Kurs said...

Thanks a lot for these Bytearray examples, I may switch to AS3 just because of this class! It really saves us a lot of memory and time compared to AS2.

Monday, July 23, 2007 5:46:00 PM  
Anonymous <a href="http://drugscenterhere.com">ShopMan</a> said...

I like articles like this. Thanks!

Sunday, August 26, 2007 12:37:00 AM  
Anonymous <a href="http://m1.aol.com/phentermine4">Phentermine</a> said...

Great Article! Thank You!

Tuesday, August 28, 2007 5:38:00 PM  
Anonymous <a href="http://m1.aol.com/phentermine4">Buy Phentermine</a> said...

Thanks to author! I like articles like this, very interesting.

Wednesday, August 29, 2007 5:03:00 AM  
Anonymous <a href="http://free-metro-pcs-ringtones.blogspot.com">Free Ringtones</a> said...

nice blog!

Sunday, September 02, 2007 2:56:00 PM  
Anonymous <a href="http://buy-viagra2007.blogspot.com">buy viagra</a> said...

nice blog!Nice information

Monday, September 03, 2007 6:09:00 PM  
Anonymous <a href="http://buy-levitra--ooz.blogspot.com">Levitra</a> said...

:-) ochen\' zaebatyj blog!

Tuesday, September 04, 2007 6:45:00 AM  
Anonymous <a href="http://search.cnn.com/search?query=site:cialis-online-2007.blogspot.com?cialis_online.html">Anonymous</a> said...

Keep up the great work. It very impressive. Enjoyed the visit!

Sunday, September 09, 2007 4:32:00 PM  
Blogger Jowie said...

Brilliant script... Saved me lots of problems! Thanks a lot!! :)

Tuesday, October 23, 2007 8:54:00 AM  
Anonymous Mike said...

Hi!
I try to make jpg ByteArray in flash, and than send it in base64 encoding to php script, but created file is always corrupted. Can anybody share by warking code??

Thats as3:

var jpgObj: JPEGEncoder = new JPEGEncoder(100);
var imageBytes: ByteArray = jpgObj.encode (bmpData);
var params:URLVariables = new URLVariables();
params.f = Base64.encodeByteArray(imageBytes);
var request:URLRequest = new URLRequest("http://test1.local/upload.php");
request.method = URLRequestMethod.POST;
request.data = params;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, uploadCompleted);
loader.load(request);


And php:

$fp = fopen( 'file.jpg', 'wb' );
fwrite( $fp, base64_decode($_POST['f']) );
fclose( $fp );


Please help!

Sunday, November 04, 2007 6:17:00 AM  
Blogger Nishant said...

can't find base64 encoder in flex and flash cs3. some say it's in mx.utils but i couldnt find it.



HELP PLEASE

Tuesday, November 13, 2007 6:54:00 AM  
Blogger Nishant said...

HELP NEEDED

i can't find the base64 encoder in flex as well as flash cs3. should i be looking elsewhere?

Tuesday, November 13, 2007 6:56:00 AM  
Anonymous Tom said...

For some reason i always get back the jpeg data: ÿØÿà and nothing else..
can anyone shed any light on this?

my actionscript is
bmp=new BitmapData(movieClipWidth,movieClipHeight,false);
var myMatrix=new Matrix ;
myMatrix.scale(0.2,0.2);
bmp.draw(movieClip,myMatrix);

jpegEnc = new JPGEncoder(75);
var jpegDat:ByteArray = jpegEnc.encode(bmp);
trace(jpegDat);

can anyone help?
my email is thomen@optusnet.com.au

thanks,
- tom

Thursday, November 22, 2007 9:08:00 PM  
Blogger Nishant said...

encode the bytearray using the base64 encoder .. obtain from as3 corelib on google.com code

Friday, November 23, 2007 4:44:00 AM  
Blogger Mike said...

I have this working now for saving JPEGs from Flash, via AMF and PHP. Works great. Only gotcha I ran into was IE caching the image, should you be in a situation where the user is making multiple JPEGs. Solution was just to add a random querystring using something like milliseconds to the file result location in the download HD function.

Wednesday, May 21, 2008 3:50:00 AM  
Blogger Max said...

Not that I'll get a reply. But I assume this is to be imported into flash using AS3. I have set it that way and get 2 errors.

1046: Type was not found or was not a compile-time constant: .

5000: The class 'JPEGEncoder' must subclass 'flash.display.MovieClip' since it is linked to a library symbol of that type.

Friday, May 23, 2008 8:53:00 AM  
Blogger Max said...

I get these 2 errors.




1046: Type was not found or was not a compile-time constant: .





5000: The class 'JPEGEncoder' must subclass 'flash.display.MovieClip' since it is linked to a library symbol of that type.






any ideas? I'm importing the class through the publish settings.

Friday, May 23, 2008 8:57:00 AM  

Post a Comment

<< Home