In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

DisplacementMapFilter with perlineNoise

DisplacementMapFilter with perlineNoise
動く perlineNoise を DisplacementMapFilter に適用して、写真をぐにゃぐにゃさせます。
左が DisplacementMapFilter によって変形するイメージ、
右がイメージを変形させている Filter に適用されている perlinNoise の bitmapData
画像読み込みは 5ivestar さんの Proxy を使わせていただきました。
wonderfl.kayac.com/code/e40aae6e65d9f379f7cd3684d40eb710a7701a2d
// DisplacementMapFilter with perlineNoise
// 動く perlineNoise を DisplacementMapFilter に適用して、写真をぐにゃぐにゃさせます。
// 左が DisplacementMapFilter によって変形するイメージ、
// 右がイメージを変形させている Filter に適用されている perlinNoise の bitmapData
//
// 画像読み込みは 5ivestar さんの Proxy を使わせていただきました。
// wonderfl.kayac.com/code/e40aae6e65d9f379f7cd3684d40eb710a7701a2d
package {
	/**
	 * @author YOSHIDA, Akio
	 */
	import flash.display.Sprite;
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.system.Security;
	
	[SWF(width="465", height="465", frameRate="60", backgroundColor="#000000")]
	
	public class Main extends Sprite {

		private var loader:Loader;	// ローダー
		private var loading:TextField;	// ナウローディング表示
		
		// 表示イメージ
		private var displayBm:Bitmap;
		// 置き換えマップ可視化
		private var mapBm:Bitmap;

		// 置き換えマップ
		private var displacementMap:PerlinNoiseMap;
		// DisplacementMapFilter
		private var dmf:EasyDMF;
		
		
		public function Main():void {
			Security.loadPolicyFile("http://5ivestar.org/proxy/crossdomain.xml");
			// Loader 生成
			loader = new Loader();
			// イベントリスナー登録
			configureListeners(loader.contentLoaderInfo);
			
			// ロード開始
			loader.load(new URLRequest("http://5ivestar.org/proxy/http://homepage3.nifty.com/aquioux/swf/as3/wonderfl/aquioux001.jpg"));
			// ナウローディング
			loading = new TextField();
			loading.defaultTextFormat = new TextFormat("_sans", 24, 0xffffff);
			loading.text = "Now Loading...";
			loading.autoSize = "left";
			loading.x = (stage.stageWidth - loading.width) / 2;
			loading.y = (stage.stageHeight - loading.height) / 2;
			addChild(loading);
		}
		// イベントリスナー登録
		private function configureListeners(dispatcher:IEventDispatcher):void {
			dispatcher.addEventListener(Event.COMPLETE, completeHandler);
		}
		// 読み込み完了時のイベントハンドラ
		private function completeHandler(e:Event):void {
			create();
		}
		
		private function create():void {
			removeChild(loading);
			
			// 表示イメージ
			var w:uint = loader.width;
			var h:uint = loader.height;
			var margin:uint = 0;
			var bmd:BitmapData = new BitmapData(w-margin*2, h-margin*2, false, 0x000000);
			bmd.draw(loader.content, new Matrix(1, 0, 0, 1, -margin, -margin));
			displayBm = new Bitmap(bmd);
			displayBm.x = margin;
			displayBm.y = margin;
			addChild(displayBm);
			loader = null;
			// 置き換えマップ可視化
			mapBm = new Bitmap();
			mapBm.x = w;
			mapBm.y = 0;
			addChild(mapBm);
			
			// 置き換えマップと DisplacementMapFilter 生成
			dmf = new EasyDMF(new PerlinNoiseMap(w, h));
			
			// イベントハンドラ
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
		
		// イベントハンドラ
		private function enterFrameHandler(e:Event):void {
			dmf.renew();
			displayBm.filters = [dmf.filter];
			mapBm.bitmapData = dmf.filter.mapBitmap;
		}
	}
}


// DisplacementMapFilter

import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.geom.Point;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;

class EasyDMF {
	private var _filter:DisplacementMapFilter;
	private var map:IDisplacementMap;	// 置き換えマップ
	
	public function EasyDMF(map:IDisplacementMap) {
		this.map = map;

		var scale:uint = 64;
		_filter = new DisplacementMapFilter(
			map.bitmapData,
			new Point(0, 0),
			BitmapDataChannel.RED,
			BitmapDataChannel.RED,
			scale,
			scale,
			DisplacementMapFilterMode.CLAMP
		);
	}
	public function renew():void {
		map.renew();
		_filter.mapBitmap = map.bitmapData;
	}
	public function get filter():DisplacementMapFilter { return _filter; }
}


// DisplacementMap(perlineNoise)

import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.geom.Point;

class PerlinNoiseMap implements IDisplacementMap {
	private var _bitmapData:BitmapData;
	private var w:uint;
	private var h:uint;

	// perlinNoise パラメータ
	private var octaves:uint  = 2;
	private var seed:Number;
	private var channels:uint = BitmapDataChannel.RED | BitmapDataChannel.GREEN | BitmapDataChannel.BLUE;
	private var offset:Array = new Array();
	private var offx:Vector.<int> = new Vector.<int>(octaves,true);
	private var offy:Vector.<int> = new Vector.<int>(octaves,true);
	private var rate:uint = 2;
	
	public function PerlinNoiseMap(w:uint, h:uint) {
		this.w = w;
		this.h = h;
		_bitmapData = new BitmapData(w, h, false, 0x000000);
		
		seed = Math.floor(Math.random()*0xffff);
		
		for (var i:int=0; i<octaves; i++) {
			offset[i] = new Point(Math.random() * w , Math.random() * h);
			offx[i] = Math.random() * rate * 2 - rate;
			offy[i] = Math.random() * rate * 2 - rate;
		}
	}
	public function renew():void {
		for (var i:int=0; i<octaves; i++) {
			offset[i].x += offx[i];
			offset[i].y += offy[i];
		}
		_bitmapData.perlinNoise(w, h, octaves, seed, false, true, channels, false, offset);
	}
	public function get bitmapData():BitmapData { return _bitmapData; }
}


// interface of DisplacementMap

import flash.display.BitmapData;

interface IDisplacementMap {
	function renew():void;
	function get bitmapData():BitmapData;
}