スポンサーサイト

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

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

Flex2でも画像をタイル状に分割する

画像をタイル状に分割するエントリと同じようなモノをFlex2でも作ってみました。




フラッシュ版と同じように、横/縦の分割数を入力して「分割」ボタンを押すとタイルが生成されます。

ソースコードはこんなカンジ。

package {
import flash.display.*;
import flash.events.*;
// 画像をタイル状に分割するサンプル
public class Tile extends Sprite {
// 横方向分割数入力欄
private var colInput:LabelInput;
// 縦方向分割数入力欄
private var rowInput:LabelInput;
// 分割ボタン
private var splitBtn:LabelButton;
// 元画像
[Embed(source='image.jpg')]
private var ImageBitmap:Class;
private var imageBitmap:Bitmap;
// タイルの配列
private var tileArray:Array;
// コンストラクタ
public function Tile() {
// 横方向分割数入力欄作成
colInput = new LabelInput("横", "12");
addChild(colInput);
// 縦方向分割数入力欄作成
rowInput = new LabelInput("縦", "9");
rowInput.x = 70;
addChild(rowInput);
// 分割ボタン
splitBtn = new LabelButton(" 分割 ");
splitBtn.x = 140;
splitBtn.addEventListener(MouseEvent.CLICK,
onSplitBtnClick);
addChild(splitBtn);
// 画像読み込み
imageBitmap = new ImageBitmap();
imageBitmap.x = 10;
imageBitmap.y = 30;
addChild(imageBitmap);
}
// 分割ボタンクリック
private function onSplitBtnClick(evt:Event):void {
// すでに分割済みなら消去
if (tileArray) {
for each(var tile:Sprite in tileArray) {
tile.parent.removeChild(tile);
}
}
// タイルを生成
tileArray = TileBuilder.build(imageBitmap,
int(colInput.inputText),
int(rowInput.inputText),
this);
// 元画像のアルファ値を変化させる
imageBitmap.alpha = 0.25
}
}
}
import flash.display.*;
import flash.text.*;
import flash.geom.*;
import flash.events.*;
// タイル生成クラス
class TileBuilder {
// 指定したソース画像からタイルを生成し、戻します。
public static function build(src:Bitmap,
cols:int,
rows:int,
container:Sprite):Array {
var tileArray:Array = new Array();
// タイルのサイズ
var w:Number = src.width / cols;
var h:Number = src.height / rows;
// グラデーション用設定
var go:Number = 1;
var gw:Number = w - 2 * go;
var gh:Number = h - 2 * go;
var gMtx:Matrix = new Matrix();
gMtx.createGradientBox(gw, gh, Math.PI / 2);
// ハイライト用設定
var ho:Number = 1;
var hw:Number = w - 2 * ho;
var hh:Number = h * 0.4;
var hMtx:Matrix = new Matrix();
hMtx.createGradientBox(hw, hh, Math.PI / 2);
// タイル生成
for (var iy:int = 0; iy < rows; iy++) {
for (var ix:int = 0; ix < cols; ix++) {
// 画像データの切り出し
var bitmap:BitmapData
= Clipper.clip(src, w * ix, h * iy, w, h);
// Sprite作成
var tile:Sprite = new Sprite();
var g:Graphics = tile.graphics;
g.beginBitmapFill(bitmap);
g.moveTo(0, 0);
g.lineTo(0, h);
g.lineTo(w, h);
g.lineTo(w, 0);
g.lineTo(0, 0);
g.endFill();
// グラデーション
g.beginGradientFill("linear",
[0x000000, 0xFFFFFF, 0xFFFFFF],
[0.6, 0, 0.6],
[0, 127, 255],
gMtx);
g.moveTo(go, go);
g.lineTo(go, go + gh);
g.lineTo(go + gw, go + gh);
g.lineTo(go + gw, go);
g.lineTo(go, go);
g.endFill();
// ハイライト
g.beginGradientFill("linear",
[0xFFFFFF, 0xFFFFFF],
[0.95, 0.2],
[0, 255],
hMtx);
g.moveTo(ho, ho);
g.lineTo(ho, ho + hh);
g.lineTo(ho + hw, ho + hh);
g.lineTo(ho + hw, ho);
g.lineTo(ho, ho);
g.endFill();
// 位置
tile.x = src.x + w * ix;
tile.y = src.y + h * iy;
// ドラッグを可能にする
tile.useHandCursor = true;
tile.addEventListener(MouseEvent.MOUSE_DOWN,
function(evt:MouseEvent):void {
// このタイルを最前面に
evt.target.parent.setChildIndex(evt.target,
evt.target.parent.numChildren - 1);
// ドラッグ開始
evt.target.startDrag();
});
tile.addEventListener(MouseEvent.MOUSE_UP,
function(evt:MouseEvent):void {
// ドラッグ終了
evt.target.stopDrag();
});
// 親と配列に追加
tileArray.push(tile);
container.addChild(tile);
}
}
return tileArray;
}
}
// 画像クリッピングクラス
class Clipper {
// 指定した位置/サイズで画像を切り取ります。
public static function clip(src:Bitmap,
x:Number,
y:Number,
w:Number,
h:Number):BitmapData {
// 切り取りサイズ
var rect:Rectangle = new Rectangle(0, 0, w, h);
// 位置
var mtx:Matrix = new Matrix();
mtx.tx = -x;
mtx.ty = -y;
// 切り取り
var bitmap:BitmapData = new BitmapData(w, h, true);
bitmap.draw(src,
mtx,
new ColorTransform(),
"normal",
rect,
true);
return bitmap;
}
}
// ラベル付き入力フィールド
class LabelInput extends Sprite {
// ラベル
private var label:TextField;
// 入力フィールド
private var input:TextField;
// コンストラクタ
public function LabelInput(labelText:String,
inputDefault:String) {
// フォーマット
var format:TextFormat=new TextFormat();
format.font = "_等幅";
format.size = 10;
format.color = 0x000000;
// ラベル生成
label = new TextField();
label.setTextFormat(format);
label.autoSize = TextFieldAutoSize.LEFT;
label.text = labelText;
addChild(label);
// 入力欄生成
input = new TextField();
input.border = true;
input.type = TextFieldType.INPUT;
input.setTextFormat(format);
input.x = label.x + label.width;
input.width = 50;
input.height = label.height;
input.text = inputDefault;
addChild(input);
}
// 入力文字列を戻します。
public function get inputText():String {
return input.text;
}
}
// ラベル付きボタン
class LabelButton extends Sprite {
// コンストラクタ
public function LabelButton(labelText:String) {
// フォーマット
var format:TextFormat=new TextFormat();
format.font = "_等幅";
format.size = 10;
format.color = 0x000000;
// ラベル生成
var label:TextField = new TextField();
label.setTextFormat(format);
label.text = labelText;
label.autoSize = TextFieldAutoSize.CENTER;
label.border = true;
label.background = true;
label.backgroundColor = 0xdddddd;
label.selectable = false;
label.mouseEnabled = false;
addChild(label);

buttonMode = true;
}
}
Tileがメインのクラスです。コンストラクタで入力欄やらボタンやら元画像を配置しています。

onSplitBtnClick(Event)が「分割」ボタンをクリックしたときに実行するメソッドで、タイルを全消去してからTileBuilderクラスを使ってタイルを生成しています。

TileBuilderクラスのbuildメソッドでタイルとなるスプライトをnewしています。Sprite#graphicsプロパティのメソッドを使って画像/グラデーション/ハイライトを描画していますが、内容的にはFlashでMovieClipのドローメソッドを使うのと変わんないカンジです。
アルファが0~1なのがチガウといえばチガウ点。

タイルをドラッグするためのイベントハンドラはSprite#addEventListenerを使ってマス。マウスボタン押下時にはstartDrag以外にSpriteを前面に持ってくる処理をしてますが、このやり方もFlashとはチガウ点ですねー。

元画像からタイル用の画像を切り出す処理はClipper#clipでやってます。コレはflashとまったく同じやり方で、BitmapData#drawを使ってマス。

上記ソースコードを
mxmlc -default-size 450 400 -default-frame-rate=12 -default-background-color=0xFFFFFF Tile.as
とかやってswfにしてます。
スポンサーサイト

テーマ:プログラミング - ジャンル:コンピュータ

2007.06.01 | | Comments(0) | Trackback(0) | Flex2

コメント

コメントの投稿


秘密にする

«  | HOME |  »

プロフィール

HundredthMonkey

Author:HundredthMonkey
プログラマ。

ブロとも申請フォーム

この人とブロともになる

メールフォーム

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

ブログ内検索


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