I took this from the old blog because it’s good shit.
I’ve been working on letting users save a jpeg from Flash to their own machine, which for the most part is no biggy even in AS2. The problem area for AS2 is the amount of data that must be sent to the server – typically an array of color values, one for every pixel in the image. So, even a small 200×200 image will generate an array with 40,000 entries – each being a 6 byte hex value. And, when you turn that into a string for posting to the server you get a 1 byte comma added between each entry. So, a 200×200 image turns into approximately a 280K upload – that will likely end up being a 30K jpeg. Which is crap.
So, the trick is to try and minimize the amount of data you send, which can be done in various ways including things like base64 encoding, or using LZW compression. I did try those methods, and while they do work, they were taking far too long (at least in VM1) to do their thing. Uploading the big-ass string was faster than compressing and uploading the small version. I was resigned to just sending the big string, but kept thinking there must be a way to somewhat minimize the impact. That’s when I hit on this simple array compression technique that is reminiscent of RLE.
Here’s the function:
function compressArray(orig:Array):Array{ var l = orig.length; var comp:Array = new Array(); //new compressed array for(var i = 0; i < l; i++){ comp[i] = “”; } comp[0] = orig[0]; var lastEqualIndex = 0; for(var i = 1; i < l; i++){ if(orig[i] != comp[lastEqualIndex]){ //new color comp[i] = orig[i]; lastEqualIndex = i; } } return comp; }
It works like so – a new array, comp, is created, the same length as the original, and filled with “” – empty strings.
The first item in the new array is set to the first item in the original, and the initial 0 index is stored in lastEqualIndex – since the two arrays are now identical at index 0.
The original array is then iterated starting at the second item in the array – index 1, and going to the end. If the current item in the original array is different from the item in the comp array at the lastEqualIndex, then a new value has been encountered. It is stored in the new, comp, array and the lastEqualIndex is updated to reflect the current index in the loop.
What this accomplishes is creating a new array where runs of duplicate data are eliminated and only the initial value in the run is kept. The other items in the run are kept at their initial empty string values.
Example:
original: [FFFFFF, FFFFFF, AAAAAA, BBBBBB, AAAAAA, AAAAAA, AAAAAA, AAAAAA]
new version: [FFFFFF, , AAAAAA, BBBBBB, AAAAAA, , , ]
original: 55 bytes
new version: 31 bytes
A full 44% reduction
Here’s some actual examples when the array is filled with color values:
As you can see, some images are more compressible than others, as is normal. I couldn’t believe the last image saw an 86% reduction, I expected much worse from it.
The nice thing about this method, aside from the fact that it’s extremely fast, is that the array indexes are preserved and so it’s very easy to reconstruct the original array: If a value in the array is “”, just use the last item (color) that wasn’t empty. Simple as that.

