Asial Blog

Recruit! Asialで一緒に働きませんか?

AS3のBitmapFilterを片っぱしから試してみる

カテゴリ :
フロントエンド(HTML5)
タグ :
Tech
ActoinScript
Flex
Filter
画像処理
こんにちは。松田です。
今年も早いものでいつの間にかエイプリルフールをむかえてしまったようですが、なんのネタも用意して無かったのでいたってふつうのブログです。
今回はActionScriptで画像処理をするには欠かせない、BitmapFilter類を試してみます。

今回はflash.filtersから以下のフィルターを試しています。
  1. BevelFilter
  2. BlurFilter
  3. GlowFilter
  4. DropShadowFilter
  5. ColorMatrixFilter
  6. ConvolutionFilter
  7. DisplacementMapFilter

片っ端からとかいいながら全部のフィルターは試してないです。ごめなさい。
ちょっとだけ嘘つきました。
それぞれどんな効果があるのか、Adobeの解説ページを読むよりも実際に見てみた方が分かりやすいと思うので、実際に実装したswfを置いています。
ボタンをいろいろ押しまくって確認してみてください。



動かしてみるとそれぞれのフィルターの使い道が何となく分かるかと思います。
が、ColorMatrixFilter, ConvolutionFilter, DisplacementMapFilterあたりは使用方法が幅広く、使い方次第でいろんなことが出来てしまうフィルターです。
ですので、今回はその中から使い道を一つだけ選んで使用してます。

ソースコードは上のフラッシュ内で右クリックして「ソースの表示」を押してください。
一応下にも載せておきますが上記方法のほうが見やすいと思います。
こんなに簡単なコードでこれだけ多彩な画像処理が行えてしまうのもASの魅力ですね。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="330" height="300" creationComplete="init()" viewSourceURL="srcview/index.html">
  3.   <mx:Canvas left="0" top="0" bottom="0" right="0" backgroundColor="gray">
  4.     <mx:Image id="image" source="@Embed(source='assets/image.png')"  x="10" y="10" />
  5.     <mx:Button x="10" y="146" label="もとにもどす" click="revertImage()"/>
  6.     <mx:Button x="10" y="176" label="Bevel" click="applyBevelFilter()"/>
  7.     <mx:Button x="76" y="176" label="Blur" click="applyBlurFilter()"/>
  8.     <mx:Button x="131" y="176" label="Glow" click="applyGlowFilter()"/>
  9.     <mx:Button x="192" y="176" label="DropShadow" click="applyDropShadowFilter()"/>
  10.     <mx:Button x="10" y="206" label="ColorMatrix (GrayScale変換)" click="applyColorMatrixFilter()"/>
  11.     <mx:Button x="10" y="236" label="Convolution (エッジ検出)" click="applyConvolutionFilter()"/>
  12.     <mx:Button x="10" y="268" label="DisplacementMap(波打ち)" click="applyDisplacementMapFilter()"/>
  13.   </mx:Canvas>
  14.   
  15.   <mx:Script>
  16.     <![CDATA[
  17.       import flash.filters.*;
  18.       
  19.       // 表示されている画像のBitmapData
  20.       private var bitmapData:BitmapData;
  21.       
  22.       // もともとの画像のBitmapData もとにもどす用
  23.       private var baseBitmapData:BitmapData;
  24.       
  25.       /**
  26.       * 初期設定
  27.       */
  28.       public function init():void 
  29.       {
  30.         // Imageオブジェクトに読み込んだ画像をBitmapDataに変換して変数に格納しておく
  31.         // このbitmapDataを操作してImageに上書きすることでフィルターをかける
  32.         // もとの画像より大きくなるフィルターもあるので大きめに作っておきますん
  33.         this.bitmapData = new BitmapData(this.image.width + 50, this.image.height + 50, true, 0x000000);
  34.         this.bitmapData.draw(this.image);
  35.         
  36.         // もとの画像に戻すために初期のBitmapDataを別に保存しておく
  37.         this.baseBitmapData = new BitmapData(this.image.width + 50, this.image.height + 50, true, 0x000000);
  38.         this.baseBitmapData.copyPixels(this.bitmapData, this.bitmapData.rect, new Point(0,0));
  39.       }
  40.       
  41.       
  42.       /**
  43.       * もとに戻す
  44.       * 初期のBitmapDataを現在のBitmapDataにコピーして上書き
  45.       */ 
  46.       private function revertImage():void
  47.       {
  48.         this.bitmapData.copyPixels(this.baseBitmapData, this.baseBitmapData.rect, new Point(0,0));
  49.       }
  50.       
  51.       
  52.       
  53.       /**
  54.       * BevelFilter
  55.       * 
  56.       * ベベル効果?日本語での用語はないのかな
  57.       * 縁取りをして立体っぽく見せる効果
  58.       */
  59.       private function applyBevelFilter():void
  60.       {
  61.         var filter:BevelFilter = new BevelFilter();
  62.         
  63.         this.applyFilterToImage(filter);
  64.       }
  65.       
  66.        
  67.       /**
  68.       * BlurFilter
  69.       * 
  70.       * 画像をぼかす
  71.       */
  72.       private function applyBlurFilter():void
  73.       {
  74.         var filter:BlurFilter = new BlurFilter();
  75.         
  76.         this.applyFilterToImage(filter);
  77.       }
  78.        
  79.       
  80.       /**
  81.       * GlowFilter
  82.       * 
  83.       * 縁取りをして光らせたりする
  84.       */
  85.       private function applyGlowFilter():void
  86.       {
  87.         var filter:GlowFilter = new GlowFilter(0xFFFFFF, 1, 10, 10, 5, 3, true, false);
  88.         
  89.         this.applyFilterToImage(filter);
  90.       }
  91.        
  92.       
  93.       /**
  94.       * DropShadowFilter
  95.       * 
  96.       * 画像に影をつける
  97.       */
  98.       private function applyDropShadowFilter():void 
  99.       {
  100.         var filter:DropShadowFilter = new DropShadowFilter(20);
  101.         
  102.         this.applyFilterToImage(filter);
  103.       }
  104.       
  105.       
  106.       /**
  107.       * ColorMatrixFilter
  108.       * 
  109.       * 画像のRGB+Alpha値をマトリクスを使って変換する
  110.       * 今回はこれを使ってグレースケールに変換
  111.       * 
  112.       * ここの解説が分かりやすい
  113.       * http://d.hatena.ne.jp/umezo/20090122/1232627694
  114.       */
  115.       private function applyColorMatrixFilter():void
  116.       {
  117.         var filter:ColorMatrixFilter = new ColorMatrixFilter([
  118.           1/3, 1/3, 1/3, 0, 0,
  119.           1/3, 1/3, 1/3, 0, 0,
  120.           1/3, 1/3, 1/3, 0, 0,
  121.           1/3, 1/3, 1/3, 0, 0,
  122.           0, 0, 0, 255, 0
  123.         ]);
  124.         
  125.         this.applyFilterToImage(filter);
  126.       }
  127.       
  128.       
  129.       /**
  130.       * ConvolutionFilter
  131.       * 
  132.       * 畳込みフィルタ
  133.       * 配列で指定したフィルタリングを画像の各ピクセルに適用していく
  134.       * ぼかし、エッジ検出、シャープ、エンボス、ベベル・・・とかがこれ1つで実現できるらしい
  135.       * 
  136.       * 下のコードは、対象のピクセルの周り8ピクセルを-1で弱めて、その分中心の1ピクセルを強調させてエッジ検出している例
  137.       * 
  138.       * 参照
  139.       * http://www.imajuk.com/blog/archives/2009/02/convolutionflter.html
  140.       */
  141.       private function applyConvolutionFilter():void
  142.       {
  143.         var filter:ConvolutionFilter = new ConvolutionFilter(3, 3,
  144.           [
  145.             -1, -1, -1,
  146.             -1, +8, -1,
  147.             -1, -1, -1 
  148.           ]
  149.         );
  150.         
  151.         this.applyFilterToImage(filter);
  152.       }
  153.       
  154.        
  155.       /**
  156.       * DisplacementMapFilter
  157.       * 
  158.       * 置き換えフィルタ
  159.       * 画像を波打たせたりぼかしたりできる
  160.       * perlinNoise(ランダムな模様を生成する)と組み合わせて画像を波打たせる効果を作ることが多いらしい
  161.       * 
  162.       * perlinNoiseについてはここを参照
  163.       * http://d.hatena.ne.jp/kkanda/20080224/p1
  164.       * 
  165.       * DisplacementMapFilterについてはこちらを参照
  166.       * http://d.hatena.ne.jp/kkanda/20080305/p1
  167.       * http://endlessblank.com/blog/2009/06/displacementmapfilter.html
  168.       */
  169.       private function applyDisplacementMapFilter():void
  170.       {
  171.         // ランダムな縞模様を生成
  172.         var perlinNoiseBitmap:BitmapData = new BitmapData(this.bitmapData.width, this.bitmapData.height);
  173.         perlinNoiseBitmap.perlinNoise(
  174.           perlinNoiseBitmap.width, 
  175.           perlinNoiseBitmap.height, 
  176.           10, 
  177.           Math.floor(Math.random() * 65535), 
  178.           false, 
  179.           true
  180.         );
  181.         
  182.         // 生成したランダムな模様を利用して波打たせる
  183.         var filter:DisplacementMapFilter = new DisplacementMapFilter(
  184.           perlinNoiseBitmap,  // 変換の元となるBitmapData
  185.           new Point(0, 0),    // 変換開始ポイント
  186.           1, // x座標の変形に使用する色 1=red, 2=green, 3=blue, 4=alpha
  187.           1, // y座標の変形に使用する色
  188.           30,// x座標の乗数
  189.           30 // y座標の乗数
  190.         );
  191.           
  192.         this.applyFilterToImage(filter);
  193.       }
  194.       
  195.       
  196.       
  197.       /**
  198.       * ここで実際にフィルターをかける
  199.       * 修正したBitmapDataをImageオブジェクトに反映させるには、
  200.       * BitmapData を Bitmap オブジェクトに格納した後に Image.load(Bitmap) を使う
  201.       */
  202.       private function applyFilterToImage(filter:BitmapFilter):void 
  203.       { 
  204.         // フィルターかけて
  205.         this.bitmapData.applyFilter(this.bitmapData, this.bitmapData.rect, new Point(0, 0), filter);
  206.         
  207.         // BitmapはBitmapDataを入れておく器
  208.         var bitmap:Bitmap = new Bitmap(this.bitmapData);
  209.         
  210.         // ここでImageに反映!
  211.         this.image.load(bitmap);
  212.       }
  213.       
  214.     ]]>
  215.   </mx:Script>
  216. </mx:Application>



参考にさせて頂いたURL
* http://d.hatena.ne.jp/umezo/20090122/1232627694
* http://www.imajuk.com/blog/archives/2009/02/convolutionflter.html
* http://d.hatena.ne.jp/kkanda/20080224/p1
* http://d.hatena.ne.jp/kkanda/20080305/p1
* http://endlessblank.com/blog/2009/06/displacementmapfilter.html