JPEG Async Encoder class meets merging multi-BitmapData

I often use PNG/JPEG Encoding in Flash and during my projects I faced some problems with this classes.
The main problem is speed and CPU usage when encoding large BitmapData objects. First I decided to rewrite PNG Encoder class provided by Tinic Uro and optimized by Aral but we cant make it encoding data asynchronous because it is using built in ByteArray compress method to GZIP image data. When encoder calls this method on large data Flash Player completely freezes. It can take up to 15 seconds to compress data. And you can do nothing all this time but waiting. May be there is an alternate way to compress ByteArray but I didnt find any.

So I turned to JPEG Encoder class provided by Adobe. After some research I found a solution forAsync Encoding. As far as it was designed for Flex I rewrite the class merging everything in one file. Now it is all in one solution. You can encode BitmapData and ByteArray objects Async listening for Progress and Complete Events or encode data through one method call.
I’ve also added method for merging several BitmapData objects in to one JPEG image. This method is very useful when you need to generate large image but can’t do it because of the Flash built in BitmapData size restrictions.
I’m using this class in my Flickr Mosaic engine to encode result mosaic image. See it in action merging several BitmapData objects into one JPEG file.

Class itself could be seen in my Google Code repository within Flickr Mosaic sources.

See some usage examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import ru.inspirit.utils.JPGEncoder;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.utils.ByteArray;
 
var bmp1:BitmapData = new BitmapData(640, 400, false, 0xFF0000);
var bmp2:BitmapData = new BitmapData(640, 400, false, 0x00FF00);
var bmp3:BitmapData = new BitmapData(640, 400, false, 0x0000FF);
var bmp4:BitmapData = new BitmapData(640, 400, false, 0xFFFF00);
 
var je:JPGEncoder = new JPGEncoder(90);
je.addEventListener(ProgressEvent.PROGRESS, onEncodingProgress);
je.addEventListener(Event.COMPLETE, onEncodingComplete);
 
// Encoding several BitmapData objects into one image
// You should provide 'square' of Bitmaps in 2 dimensional array
je.encodeMultiToOne([
				[bmp1, bmp2],
				[bmp3, bmp4]
				]);
 
// Simple encode
/*
var ImageByteArray:ByteArray = je.encode(bmp1); 
*/
 
// Async encode
// You should provide listeners (see above) to handle data ready event
/*
je.encodeAsync(bmp1);
*/
 
private function onEncodingComplete(e:Event):void 
{
	// Async Encoding Complete
	var ImageByteArray:ByteArray = je.ImageData;
}
 
private function onEncodingProgress(e:ProgressEvent):void 
{
	trace('ENCODING PROGRESS: ' + Math.round(e.bytesLoaded/e.bytesTotal * 100) + '%');
}


转载:http://blog.inspirit.ru/?p=201

你可能感兴趣的:(JPEG Async Encoder class meets merging multi-BitmapData)