2007年10月09日
AS3 でヒストグラムを作る (1)
今週は ActionScript でヒストグラムを作っていきます。画像の色分布をグラフ表示したやつです。
手順:
- 1. グレースケール化
- 最初に各チャンネルの平均をとるために白黒画像にします。ColorMatrixFilter を使えば一発ですね。
- 2. threshold でカウント
- 各階調のピクセル数を調べるために threshold を使います。threshold は戻り値でマッチしたピクセル数が返ってくるので、これを利用します。
- 3. 描画
- lineTo で描画します。
高速化の余地はありそうだけど、複雑になりそうなのでこのへんで。
次回からはヒストグラムを操作できるようにしていきます。
ソースコードは以下に(45行)。
package { import flash.display.*; import flash.filters.ColorMatrixFilter; import flash.geom.Point; [SWF(width="256", height="276")] public class Histogram1 extends Sprite { [Embed(source="yoshijima.jpg")] private var SampleImage:Class; public function Histogram1() { var bmd:BitmapData = Bitmap(addChild(new SampleImage())).bitmapData; var s:Sprite = new Sprite(); createHistogram(bmd,s); addChild(s).y = bmd.height + 10; } // ヒストグラムを作成する private function createHistogram(bmd:BitmapData, s:Sprite):void { // グレースケール化 var cmf:ColorMatrixFilter = new ColorMatrixFilter( [1 / 3, 1 / 3, 1 / 3, 0, 0, 1 / 3, 1 / 3, 1 / 3, 0, 0, 1 / 3, 1 / 3, 1 / 3, 0, 0] ); var bmd2:BitmapData = bmd.clone(); bmd2.applyFilter(bmd2, bmd2.rect, new Point(), cmf); // threshold でカウント var values:Array = []; for(var i:int = 0; i < 0x100; i++) { values[i] = bmd2.threshold(bmd2, bmd2.rect, new Point(), "==", i, 0, 0xff, false); } bmd2.dispose(); // 描画 var max:int = bmd.width * bmd.height / 50; s.graphics.lineStyle(1); for(i = 0; i < 0x100; i++) { s.graphics.moveTo(i, 100); s.graphics.lineTo(i, Math.max(0, 100 - values[i] / max * 100)); } } } }