2007-11-09 | 17:02
DisplacementMapFilterとは置き換え画像の色情報に基づいて画像を変形させるという、少しわかりづらいフィルタ。
置き換えマップのRGBとアルファ値をもとにX方向Y方向の変形を指定するが、話を簡単にするために青成分を使ってX方向だけに変形することを考える。
1行目は、上1/3が(青の)輝度0、次の1/3が輝度128、下の1/3が輝度255になっている。適用後の画像は上が右にずれ、中は移動せず、下は左にずれている。
2行目は、下に行くほど輝度が高くなっている。適用後の画像は斜めに直線的にずれている。(「画像を平行四辺形に変形」でも説明したようにこのような線形の変形は行列を使えば簡単にできる。)
3行目はサインカーブに応じて輝度を変えている。適用後の画像は波打ったようになる。
4行目は右側が円状に変形するようにしてみたもの。
ソース
置き換えマップのRGBとアルファ値をもとにX方向Y方向の変形を指定するが、話を簡単にするために青成分を使ってX方向だけに変形することを考える。
各行はそれぞれ、元画像、置き換えマップの適用後の画像、置き換えマップ画像になっている。
1行目は、上1/3が(青の)輝度0、次の1/3が輝度128、下の1/3が輝度255になっている。適用後の画像は上が右にずれ、中は移動せず、下は左にずれている。
2行目は、下に行くほど輝度が高くなっている。適用後の画像は斜めに直線的にずれている。(「画像を平行四辺形に変形」でも説明したようにこのような線形の変形は行列を使えば簡単にできる。)
3行目はサインカーブに応じて輝度を変えている。適用後の画像は波打ったようになる。
4行目は右側が円状に変形するようにしてみたもの。
ソース
package {
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
[SWF(width='500',height='600',backgroundColor='0xffffff')]
public class Main extends Sprite {
[Embed(source="lena.jpg")]
private var myImage:Class;
public function Main( ) {
transformByDMF(0, createMap);
transformByDMF(1, createMap2);
transformByDMF(2, createMap3);
transformByDMF(3, createMap4);
}
private function transformByDMF(i:int, f:*):void{
var bm1:Bitmap = new myImage();
var bm2:Bitmap = new myImage();
addChild(bm1);
bm2.x = bm1.width + 10;
bm1.y = bm2.y = (bm1.height+10)*i;
addChild(bm2);
var bmd:BitmapData = f(bm1.width, bm1.height);
var f2:DisplacementMapFilter = new DisplacementMapFilter(bmd, new Point(0,0),
BitmapDataChannel.BLUE,BitmapDataChannel.BLUE, 100,0,"color",0x0);
bm2.filters = [f2];
var bm3:Bitmap = new Bitmap(bmd);
bm3.x = bm1.width + bm2.width + 20;
bm3.y = bm1.height*i + 10*i;
addChild(bm3);
}
private function createMap(width:int, height:int):BitmapData{
var bmp:BitmapData = new BitmapData(width, height, false, 0xffffff);
for(var j:int = 0; j < height; j++){
for(var i:int = 0; i < width; i++){
var col:int;
if(j < height/3)
col = 0;
else if(j < height*2/3)
col = 128;
else col = 255;
bmp.setPixel(i, j, col);
}
}
return bmp;
}
private function createMap2(width:int, height:int):BitmapData{
var bmp:BitmapData = new BitmapData(width, height, false, 0xffffff);
for(var j:int = 0; j < height; j++){
for(var i:int = 0; i < width; i++){
var col:int = 256/height * j;
bmp.setPixel(i, j, col);
}
}
return bmp;
}
private function createMap3(width:int, height:int):BitmapData{
var bmp:BitmapData = new BitmapData(width, height, false, 0xffffff);
for(var j:int = 0; j < height; j++){
for(var i:int = 0; i < width; i++){
bmp.setPixel(i, j, 64*Math.sin(Math.PI*2/height*j) + 128);
}
}
return bmp;
}
private function createMap4(width:int, height:int):BitmapData{
var bmp:BitmapData = new BitmapData(width, height, false, 0xffffff);
for(var j:int = 0; j < height; j++){
for(var i:int = 0; i < width; i++){
var y:Number = height/2 - (j+1);
var a:Number = width;
var b:Number = height/2;
// yに対応するx
var x:Number = Math.sqrt(a*a*(b*b-y*y)/(b*b));
var l:Number = 128*(2-x/width);
bmp.setPixel(i, j, l);
}
}
return bmp;
}
}
}

Comment
Post a comment