波紋のような画像エフェクト

(サンプル一覧を表示する)

FlashDevelop を使って、波紋のような画像エフェクトのテストをしてみました。

1 ピクセルずつ getPixel, setPixel しているので処理が重いです。
ピクセルの処理を setPixels を使うように変更して、Math.sin / Math.cos の呼び出しをテーブル化すると軽くなると思います。

写真素材は、LittleHut さんからお借りしました。
Flash の実行画面
波紋のような画像エフェクト

Flashプレーヤーが入っていないか、JavaScriptが無効になっているようです。

Get Adobe Flash player

波紋のような画像エフェクト
処理が重いので、5 フレーム/秒で表示しています。

ソースコード

package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	
	/**
	 * 波紋のような画像エフェクトのサンプル
	 * @author Hikipuro
	 */
	public class Main extends Sprite 
	{
		/**
		 * 埋め込み画像
		 */
		[Embed(source='../image/test001.jpg')]
		private var image:Class;
		
		/**
		 * 転送元画像のビットマップデータ
		 */
		private var bitmapData1:BitmapData;
		
		/**
		 * 転送先画像のビットマップデータ
		 * (ここに入れた画像が表示される)
		 */
		private var bitmapData2:BitmapData;
		
		/**
		 * 中心点からの距離をあらかじめ計算しておくテーブル
		 */
		private var length:Array;
		
		/**
		 * 中心点から見た角度をあらかじめ計算しておくテーブル
		 */
		private var angle:Array;
		
		/**
		 * 1 フレーム経過するごとに一定量ずつ値を足す
		 */
		private var frameCount:Number = 0;
		
		/**
		 * コンストラクタ
		 */
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		/**
		 * 初期化イベント
		 * @param	e
		 */
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			// 埋め込み画像をビットマップに入れる
			var sourceBitmap:Bitmap;
			sourceBitmap = Bitmap(new image);
			
			// 転送元ビットマップデータ・転送先ビットマップデータを準備
			bitmapData1 = new BitmapData(320, 240);
			bitmapData2 = new BitmapData(320, 240);
			bitmapData1.draw(sourceBitmap);
			
			// 中心点からの距離と角度をあらかじめ計算しておく
			length = new Array();
			angle = new Array();
			
			for (var y:int = 0; y < 240; y++)
			{
				length[y] = new Array();
				angle[y] = new Array();
				
				for (var x:int = 0; x < 320; x++)
				{
					length[y][x] = Math.sqrt(Math.pow(x - 160, 2) + Math.pow(y - 120, 2));
					angle[y][x] = Math.atan2(y - 120, x - 160);
				}
			}
			
			// 転送先ビットマップデータを画面に表示する
			addChild(new Bitmap(bitmapData2));
			
			// フレーム開始イベントの登録
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		/**
		 * フレーム開始イベント
		 * @param	event
		 */
		private function onEnterFrame(event:Event):void 
		{
			// フレーム数のカウンタを更新
			frameCount -= 2;
			
			// 1 ピクセルずつ処理する
			for (var y:int = 0; y < 240; y++)
			{
				for (var x:int = 0; x < 320; x++)
				{
					var len:Number = Math.sin(length[y][x] * 0.5 + frameCount) + length[y][x];
					var sx:int = 160 + Math.cos(angle[y][x]) * len;
					var sy:int = 120 + Math.sin(angle[y][x]) * len;
					var color:uint = bitmapData1.getPixel(sx, sy);
					bitmapData2.setPixel(x, y, color);
				}
			}
		}
		
	}
	
}
		

外部リンク