スポンサーサイト

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

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

Flash CS3でレンズ

マウスカーソルを画像の上にもってくと、レンズっぽく拡大されます。
レンズで部分拡大のCS3版デス。





以前エントリしたモノと同じで、入力値にあわせてDisplacementMapFilterを作って、マウスカーソル周辺の画像に適用しています。
右側に出る青緑っぽい画像が、生成したマップ画像です。

今回は、レンズ用のDisplacementMapFilterを生成するファクトリクラスとフレームアクションで構成してみました。

ファクトリクラス(LensFilterFactory.as)はこんなカンジです。

package {
import flash.display.BitmapData;
import flash.filters.DisplacementMapFilter;
import flash.geom.Point;
/**
* レンズフィルタのファクトリ。
*/
public class LensFilterFactory {
/**
* レンズとしてはたらくDisplacementMapFilterを生成し、
* 戻します。
* @param size レンズの直径
* @param r レンズの曲率半径
* @param f レンズの焦点距離
* @return レンズとしてはたらくDisplacementMapFilter
*/
public static function create(size:Number,
r:Number,
f:Number)
:DisplacementMapFilter {
var mapData:BitmapData
= new BitmapData(size, size, false, 0xFF008080);
var o:Number = size / 2;
var o2:Number = o * o;
var r2:Number = r * r;
var y:Number;
var dY:Number;
var dY2:Number;
var x:Number;
var dX:Number;
var dR2:Number;
var l:Number;
var d:Number
// 調整値を割り出す
var maxY:Number = 0;
var maxX:Number = 0;
for (y = 0; y < size; y++) {
dY = y - o;
dY2 = dY * dY;
for (x = 0; x < size; x++) {
dX = x - o;
dR2 = dX * dX + dY2;
// ピクセルが、レンズムービークリップの内接円に
// 入っている場合のみ処理
if (dR2 < o2) {
// ずれ
l = Math.sqrt(r2 - dR2) - Math.sqrt(r2 - o2);
d = l / (f + l);
// 最大値設定
maxY = Math.max(maxY, Math.abs(dY * d));
maxX = Math.max(maxX, Math.abs(dX * d));
}
}
}
var yAdj:Number = 128 / (maxY + 1);
var xAdj:Number = 128 / (maxX + 1);
// ビットマップ生成
for (y = 0; y < size; y++) {
dY = y - o;
dY2 = dY * dY;
for (x = 0; x < size; x++) {
dX = x - o;
dR2 = dX * dX + dY2;
// ピクセルが、レンズムービークリップの内接円に
// 入っている場合のみ処理
if (dR2 < o2) {
// ずれ
l = Math.sqrt(r2 - dR2) - Math.sqrt(r2 - o2);
d = l / (f + l);
// ピクセルの色
var yC:Number = -Math.floor(dY * d * yAdj);
var xC:Number = -Math.floor(dX * d * xAdj);
var c:Number = 0xFF000000
+ (0x80 + yC) * 0x100
+ (0x80 + xC);
// ピクセルを描画する
mapData.setPixel(x, y, c);
}
}
}
// フィルタ生成
var filter:DisplacementMapFilter
= new DisplacementMapFilter(mapData,
new Point(),
4,
2,
Math.ceil(256 / xAdj),
Math.ceil(256 / yAdj));
return filter;
}
}
}
staticなcreateメソッドを、レンズの直径/曲率半径/焦点距離をパラメータにして実行すると、レンズ用のマップ画像がセットされたDisplacementMapFilterを生成して戻します。
コレで作ったフィルタを、レンズ拡大したい画像に適用すればイイって寸法デス。

で、サンプルフラッシュのフレームアクションはこんなカンジです。
import flash.filters.DisplacementMapFilter;
// レンズ
var lens:Sprite = new Sprite();
lens.mouseEnabled = false;
lens.visible = false;
addChild(lens);
// レンズ部分画像
var clipImage:Bitmap;
// 置き換えビットマップ
var mapBitmap:Bitmap;
// 設定ボタンを押したとき
test_btn.addEventListener(MouseEvent.CLICK, setupFilter);
var size:Number;
var r:Number;
var f:Number;
setupFilter(null);
// 設定にしたがいレンズを生成しセットする
function setupFilter(evt:Event) {
size = Number(size_txt.text);
r = Number(r_txt.text);
f = Number(f_txt.text);
var filter:DisplacementMapFilter
= LensFilterFactory.create(size, r, f);
if (mapBitmap) {
removeChild(mapBitmap);
}
mapBitmap = new Bitmap(filter.mapBitmap);
addChild(mapBitmap);
mapBitmap.x = 360 - mapBitmap.width / 2;
mapBitmap.y = 160 - mapBitmap.height / 2;
lens.filters = [filter];
}
// マウスカーソルが画像の上にあったらレンズ処理
image_mc.addEventListener(MouseEvent.MOUSE_OVER,
function(e:Event) {
e.target.addEventListener(MouseEvent.MOUSE_MOVE, onLensMove);
lens.visible = true;
Mouse.hide();
});
image_mc.addEventListener(MouseEvent.MOUSE_OUT,
function(e:Event) {
e.target.addEventListener(MouseEvent.MOUSE_MOVE, onLensMove);
lens.visible = false;
Mouse.show();
});
// レンズが移動したら対象画像を更新する
function onLensMove(evt:Event) {
var bitmap:BitmapData = new BitmapData(size, size);
var mtx:Matrix = new Matrix();
mtx.tx = -image_mc.mouseX + size / 2;
mtx.ty = -image_mc.mouseY + size / 2;
bitmap.draw(image_mc,
mtx,
new ColorTransform(),
BlendMode.NORMAL,
new Rectangle(0, 0, size, size),
false);
if (clipImage) {
lens.removeChild(clipImage);
}
clipImage = new Bitmap(bitmap);
lens.addChild(clipImage);
lens.x = mouseX - lens.width / 2;
lens.y = mouseY - lens.height / 2;
}
lesというのがレンズ部分を示すスプライトで、先ほどのファクトリクラスを使って作ったDisplacementMapFilterオブジェクトをfiltersにセットしてあります。
画像の上でマウスカーソルを動かしたらonLensMoveメソッドでレンズの大きさ分画像を切り取り、lensにセットしています。
clipImageが、切り取った画像です。

mapBitmapは、作ったDisplacementMapFilterオブジェクトで使用しているマップ画像をBitmapオブジェクトにしたもので、画像の右側に表示しています。

size_txtがサイズ入力欄、r_txtが曲率半径入力欄、f_txtが焦点距離入力欄、test_btnが設定ボタンです。
スポンサーサイト

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

2007.07.05 | | Comments(0) | Trackback(1) | Flash CS3

コメント

コメントの投稿


秘密にする

トラックバック

http://100th.blog96.fc2.com/tb.php/27-59d78aa6
この記事にトラックバックする(FC2ブログユーザー)

バトーの眼 AS3版 プロトタイプ

押井守監督作品「イノセンス」。 今は公開していませんが、かつて、その素晴らしい映像表現に大いに触発されたワタクシは、「バトーの視界」をシミュレートした Swf を Flash MX 2...

2007.12.30 | 閃光的網站・弛緩複合体 -Review Division-

«  | HOME |  »

プロフィール

HundredthMonkey

Author:HundredthMonkey
プログラマ。

ブロとも申請フォーム

この人とブロともになる

メールフォーム

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

ブログ内検索


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