スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--.--.-- | | スポンサー広告

DisplacementMapFilterを使った画像の拡大/縮小

DisplacementMapFilterを使って、画像を拡大/縮小するサンプルを作ってみました。
横と縦のテキスト入力欄に数値を入力して表示ボタンを押すと、ムービークリップの中心を基準に、入力した数値で画像を拡大/縮小します。
左側が拡大/縮小後の画像、右側がそのために使用したマップ画像です。




ムービークリップの拡大/縮小は、もっとラクなやり方がイロイロあるしそっちのほーがキレイにできるのでこの方法を使う必要はないのですが、DisplacementMapFilterについてもうちょっと詳しく知りたいと思ったのでこのようなサンプルを作ってみました。

どういう風にマップ画像を生成してるかってーと、DisplacementMapFilterはマップ画像の各ピクセルでそのピクセルと表示したい元の画像のピクセルの位置の差を色として設定することで画像を変形させる。ということなので、各表示ピクセルの位置と元画像のピクセルの位置の差を求める方法を考えマス。

このサンプルの場合だと指定した値だけ拡大したいので、たとえばy軸方向について考えると、基準点のy座標をoY、表示したいピクセルのy座標をy、元の画像のピクセルのy座標をy0、y軸方向の拡大率をsYとすると、

  y - oY = sY(y0 - oY)

なハズなので、y - y0をy0なしで表記すると
  y - y0 = (y - oY)(sY - 1) / sY

で、この分だけピクセルの色を変化させりゃーいいハズ。たぶん。
↓のgetYCという関数がソレにあたります。
import flash.display.BitmapData;
import flash.filters.DisplacementMapFilter;
// 位置、サイズ
var l:Number = test_mc._x;
var t:Number = test_mc._y;
var w:Number = test_mc._width;
var h:Number = test_mc._height;

// 原点
var oX:Number = w / 2;
var oY:Number = h / 2;

// マスク画像オフセット
var maskOffsetX:Number = w + 10;
var maskOffsetY:Number = 0;

// 表示ボタン
test_btn.onRelease = doTrans;

// マスク画像
var mask_mc:MovieClip;

// スケール調整値
var yAdj:Number = 1;
var xAdj:Number = 1;

// 初期表示
doTrans();

function doTrans() {
// 倍率
var sX:Number = Number(sx_txt.text);
var sY:Number = Number(sy_txt.text);

if (mask_mc) {
mask_mc.removeMovieClip();
}
// マスク画像
var mask:BitmapData = createMask(sX, sY, oX, oY);

// マスク画像表示
var depth:Number = _root.getNextHighestDepth();
mask_mc = _root.createEmptyMovieClip("mask_" + depth, depth);
mask_mc.attachBitmap(mask, 1);
mask_mc._x = l + maskOffsetX;
mask_mc._y = t + maskOffsetY;

// フィルタ設定
var filter:DisplacementMapFilter
= new DisplacementMapFilter(mask,
new Point(),
4,
2,
Math.ceil(256 / xAdj),
Math.ceil(256 / yAdj));
test_mc.filters = [filter];
}


// マスク画像を作成し、戻す。
function createMask(sX:Number, sY:Number, oX:Number, oY:Number)
:BitmapData {
// y方向の差が128以内に収まるように調整値を設定する
var max:Number = Math.max(Math.abs(getYC(0, sY, oY)),
Math.abs(getYC(h - 1, sY, oY)));
yAdj = 128 / (max + 1);
// x方向の差が128以内に収まるように調整値を設定する
max = Math.max(Math.abs(getXC(0, sX, oX)),
Math.abs(getXC(w - 1, sX, oX)));
xAdj = 128 / (max + 1);
// ビットマップ生成
var bitmap:BitmapData = new BitmapData(w, h);
for (var y:Number = 0; y < h; y++) {
// yに対する色の明るさを求める
var yC = Math.floor(getYC(y, sY, oY) * yAdj);
for (var x:Number = 0; x < w; x++) {
// xに対する色の明るさを求める
var xC = Math.floor(getXC(x, sX, oX) * xAdj);
// このピクセルの色を算出
var c:Number = 0xFF000000 +
(0x80 + yC) * 0x100 +
xC + 0x80;
// ピクセルを描画する
bitmap.setPixel(x, y, c);
}
}
return bitmap;
}

// 指定したy座標で用いる色の明るさ(0x80との差)を戻します。
function getYC(y:Number, sY:Number, oY:Number):Number {
return -Math.round((y - oY) * (sY - 1) / sY);
}

// 指定したx座標で用いる色の明るさ(0x80との差)を戻します。
function getXC(x:Number, sX:Number, oX:Number):Number {
return -Math.round((x - oX) * (sX - 1) / sX);
}

x軸方向に関してもだいたい同じよーにやってマス。

上記ソースコード中の、差が128以内に収まるように調整値を設定する。というのはどういうことかというと、ピクセルの色と0x80の差で元ピクセルの位置を指定するため、場合によっては0x00~0xFFの範囲を超えちゃうかも知れないので、その場合は色で示す変化量を範囲内に収めて、フィルターで指定するスケールで調整してマス。
スポンサーサイト

テーマ:Flash - ジャンル:コンピュータ

2007.03.11 | | Comments(0) | Trackback(0) | Flash/ActionScript

«  | HOME |  »

プロフィール

HundredthMonkey

Author:HundredthMonkey
プログラマ。

ブロとも申請フォーム

この人とブロともになる

メールフォーム

名前:
メール:
件名:
本文:

ブログ内検索


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。