package { import flash.display.BitmapData; public class HHistogram { public function calculate(bmd:BitmapData):Object { var ret:Object = { eBmd: new BitmapData(bmd.width, bmd.height), hBmd: null }; // Calculate histogram and eImg var histogram:Array = new Array(360); for (var i = 0; i < 360; i++) { histogram[i] = 0; } for (i = 0; i < bmd.width; i++) { for (var j = 0; j < bmd.height; j++) { var c:uint = bmd.getPixel(i, j); var h:int = int(colorToHsv(c).h); if (h == 360) { h = 0; } ret.eBmd.setPixel(i, j, hsvToColor(h, 0.5, 1)); histogram[h]++; } } ret.hBmd = toBitmapData(histogram, bmd.width); return ret; } /** * Returns a bitmap data of wx360 visualizing the histogram. */ function toBitmapData(histogram:Array, w:int):BitmapData { // Find the max so that we can normalize to the width of w var max:int = histogram[0]; for (var j:int = 1; j < 360; j++) { if (max < histogram[j]) { max = histogram[j]; } } // Visualize var normalizer:Number = w/max; var ret:BitmapData = new BitmapData(w, 360); for (j = 0; j < 360; j++) { var c:Number = hsvToColor(j, 0.5, 1); for (var i:int = 0; i < histogram[j]*normalizer; i++) { ret.setPixel(i, j, c); } } return ret; } /** * h: 0-360 * s, v: 0-1.0 * * Returns RGB color. */ function hsvToColor(h:Number, s:Number, v:Number):Number { var cv:Number = Math.round(v * 255); var r:Number = cv; var g:Number = cv; var b:Number = cv; if (s > 0) { var i:Number = Math.floor(h / 60); var f:Number = h / 60 - i; var m:Number = Math.round(v * (1 - s) * 255); var n:Number = Math.round(v * (1 - s * f) * 255); var k:Number = Math.round(v * (1 - s * (1 - f)) * 255); switch (i) { case 0 : g = k; b = m; break; case 1 : r = n; b = m; break; case 2 : r = m; b = k; break; case 3 : r = m; g = n; break; case 4 : r = k; g = m; break; case 5 : g = m; b = n; break; } } return r << 16 | g << 8 | b; } /** * color: RGB color. * * Returns an object of h, s, v where * h: 0-360 * s, v: 0-1.0 */ function colorToHsv(color:Number):Object { var r:Number = color >> 16; var g:Number = (color >> 8) & 0xFF; var b:Number = color & 0xFF; var max:Number = Math.max(r, Math.max(g, b)); var min:Number = Math.min(r, Math.min(g, b)); var range:Number = max - min; var h:Number = 0; var s:Number = 0; var v:Number = max / 255; if (v > 0) { s = range / max; if (s > 0) { var cr:Number = (max - r) / range; var cg:Number = (max - g) / range; var cb:Number = (max - b) / range; if (r == max) { h = cb - cg; } else if (g == max) { h = 2 + cr - cb; } else { h = 4 + cg - cr; } h *= 60; if (h < 0) { h += 360; } } } return {h:Math.round(h * 100) * 0.01,s:Math.round(s * 100) * 0.01,v:Math.round(v * 100) * 0.01}; } } }