A while back i posted some ThreadedImageEncoder classes to convert BitmapData objects to .PNG or .JPG format over multiple Flash frames. With the arrival of ActionScript Workers i figured they would become obsolete, but we’re still waiting for Workers in mobile AIR so i’m still using them. Anyway, i needed a ‘real’ project to practice generating ASDocs with, so i chose the image encoder classes. I wasn’t planning on doing more than adding some comments, but i got carried away and ended up refactoring a lot of the code too.
Now they’re a bit more polished, i’ve renamed them to AsyncImageEncoders and given them their own github repository. In the repo you’ll find all the source code, a precompiled SWC, ASDocs for the classes and instructions on using them.
They’re easy to use:
//generate a BitmapData object to encode
var myBitmapData:BitmapData = new BitmapData(1000, 1000, true, 0x80FF9900);
//create an encoder
var encoder:IAsyncImageEncoder = new AsyncPNGEncoder();
//start encoding for 20 milliseconds per frame
trace("encoding progress:", Math.floor(event.percentComplete)+"% complete");
//trace size of result
trace("encoding completed:", encoder.encodedBytes.length+" bytes");
//do something with the bytes...
//..save to filesystem?
//..upload to server?
//..set as source for flex Image component?
There is also a stop() method if you get impatient with a long encode (large JPEGs on mobile can take ages) and an isRunning property which should need no explanation.
Lastly, the AsyncImageEncoderBase class can be extended to create other asynchronous encoders; hopefully, i will demonstrate that by adding a .BMP encoder in the next few days it took me 5 minutes to create a .BMP encoder.
I’ve noticed that this question pops up from time to time on forums, and it’s very straight-forward to do; we can use the draw() method of BitmapData to copy any visual element (in this case, the stage itself) into a BitmapData object. Then we can use the getPixel() method to extract the colour. Continue reading →
Firstly, as i realise that i haven’t actually mentioned it yet and it’s a rather important point, PixelBender filters are quick! Much quicker than ActionScript and they can also run asynchronously in a separate thread. So bear that in mind when you find out further down the page that you can’t even loop in PixelBender!
The built-in filters provided by the BitmapFilters API (blur, glow, dropshadow, bevel etc) are very useful but sometimes our imagination exceeds their capabilities. Wouldn’t it be nice if we could create our own? Yes it would, and it is; we can build our own filters with a free bit of software called PixelBender and use a ShaderFilter filter to implement them.
Before i go any further, here’s a simple example to show you how much further we can go with custom filters: Continue reading →
As i stated in part 1, encoding a large image can take a few seconds – especially if it’s a high quality jpeg. While the encoding is running, flash player is unable to advance to the next frame so the FPS drops to zero until the encoding has finished; this means that all animations will pause and keyboard and mouse actions will be ignored – not a great user experience.
What we need to do is spread the encoding over multiple frames (known as threading), ie: enough frames so that the user doesn’t notice any slow-down. Continue reading →
Since Flash Player 10, we have been able to save files directly to the users system (you could do it before, but annoyingly you had to send the file to the server and then get the server to send it back to the user – a real pain!).
Now, it couldn’t be simpler:
var file:FileReference = new FileReference();