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

38 Comments:
Very cool! thanks for sharing.
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.
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?
Unbelievable! I'm just stunned at what one can do with images with AS3.
-Danny
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?
If we generate a JPG/PNG like this, can we offer somehow to let the user to save it to disk?
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
HI TINIC
Would appreciate if you could get in touch
SU
After many hours, I totally got it working, and with a save locally or on server...........AWESOME!!!
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
Can somebody post a link to a downloadable working version of this script?
I just can't get it to work.
Thanks!
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
Anyone seen a TIFF Image decoder for Flash 9? I am trying to display a TIFF CCITT-Group 4 file in a flash application
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?
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
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.
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.
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?
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.
hi
does anyone know how i can use this package via flash cs3?
regards
ade
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.
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.
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
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.
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.
I like articles like this. Thanks!
Great Article! Thank You!
Thanks to author! I like articles like this, very interesting.
nice blog!
nice blog!Nice information
:-) ochen\' zaebatyj blog!
Keep up the great work. It very impressive. Enjoyed the visit!
Brilliant script... Saved me lots of problems! Thanks a lot!! :)
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!
can't find base64 encoder in flex and flash cs3. some say it's in mx.utils but i couldnt find it.
HELP PLEASE
HELP NEEDED
i can't find the base64 encoder in flex as well as flash cs3. should i be looking elsewhere?
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
encode the bytearray using the base64 encoder .. obtain from as3 corelib on google.com code
Post a Comment
<< Home