weighted average color
multipart project 3
part 2 of, I don't know, like 5
Background:
Suppose you have a transparent PNG. Use the pixel data to figure out an appropriate matte color.
I'm going to be taking the average color across all pixels (weighted by alpha). Highlights and shadows will desaturate this average, so increase the saturation afterwards.
Task:
- find average color
- saturate more...
/**
* Copyright wh0 ( http://wonderfl.net/user/wh0 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/2cPX
*/
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.net.*;
import flash.system.*;
import flash.utils.*;
import com.actionscriptbible.Example
public class FlashTest extends Example {
private static const PROXY:String = 'http://5ivestar.org/proxy/';
public function FlashTest() {
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, error);
Security.loadPolicyFile(PROXY + 'crossdomain.xml');
var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(Event.COMPLETE, check);
l.load(new URLRequest(PROXY + 'http://s240.photobucket.com/albums/ff85/Pokestadium/sugimori/470.png'), new LoaderContext(true));
}
private function error(e:UncaughtErrorEvent):void {
trace(e.error);
}
private function check(e:Event):void {
var li:LoaderInfo = e.target as LoaderInfo;
var d:DisplayObject = li.content;
var bd:BitmapData = new BitmapData(d.width, d.height);
bd.draw(d);
var rect:Rectangle = new Rectangle(0, 0, bd.width, 1);
// compute weighted averages of components
var red:Number = 0;
var green:Number = 0;
var blue:Number = 0;
var denominator:Number = 0;
for (var y:int = 0; y < bd.height; y++) {
rect.top = y;
rect.height = 1;
var data:ByteArray = bd.getPixels(rect);
data.position = 0;
for (var x:int = 0; x < bd.width; x++) {
var alpha:int = data.readByte() & 0xff;
denominator += alpha;
red += alpha * (data.readByte() & 0xff);
green += alpha * (data.readByte() & 0xff);
blue += alpha * (data.readByte() & 0xff);
}
}
red /= denominator;
green /= denominator;
blue /= denominator;
// increase saturation
var min:Number = Math.min(red, green, blue) * 0.8;
var max:Number = Math.max(red, green, blue) * 0.8 + 256 * 0.2;
var scale:Number = 256. / (max - min);
red = (red - min) * scale;
green = (green - min) * scale;
blue = (blue - min) * scale;
// render stuff...
var color:uint = 0xff000000 |
((red & 0xff) << 16) |
((green & 0xff) << 8) |
(blue & 0xff);
bd.fillRect(bd.rect, color);
addChild(new Bitmap(bd));
addChild(d);
}
}
}