Flex3 Menuの使い方

Flex3でのMenuの使い方


完成例はこちらのSample置き場からどうぞ
なお、ソースコードも落とすことができます


キャプチャー画面


Menuを使用すると以下のように[ファイル]と書かれたボタンを選択すると下にメニューリストを表示させることができるようになります
Flex3MenuSample_1.gif


必要なimport宣言


import mx.controls.Menu;


ソースコードのサンプル


MXML



<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" styleName="plain"
width="100%" height="100%">
<mx:Script source="BaseFunction.as" />
<!-- fileMenuListの宣言 -->
<mx:XML format="e4x" id="fileMenuList">
<root>
<menuitem label="新規" param="1" />
<menuitem label="開く" param="2" enabled="true" />
<menuitem label="保存" param="3" enabled="false" >
<menuitem label="JPEGで保存" param="31" />
<menuitem label="GIFで保存" param="32" />
</menuitem>
<menuitem label="閉じる" param="4" enabled="false" />
</root>
</mx:XML>

<mx:ApplicationControlBar id="mainMenuBar" width="100%" height="30" dock="true" backgroundColor="0x990099">
<mx:Button id="fileMenu" label="ファイル" click="showFileMenu();" />
</mx:ApplicationControlBar>
<mx:VBox width="100%" height="100%" verticalScrollPolicy="on" horizontalScrollPolicy="on" borderStyle="solid">
<mx:Image id="container" width="100%" height="100%"/>
</mx:VBox>
</mx:Application>

主要パーツの構成は以下の画像のようになっています
Flex3MenuSample_2.gif


Menuとして表示させたい項目をXMLオブジェクトとして定義しておくのがポイントです
※XMLファイルを外部読込しても可能です


BaseFunction.as


動作が記述されているActionScriptファイルです
主要部分だけ抜粋します



import mx.events.MenuEvent;
import flash.events.Event;
import mx.controls.Alert;
import mx.controls.Menu;

private var myFileMenu:Menu;

public function showFileMenu():void
{
myFileMenu = Menu.createMenu(mainMenuBar, fileMenuList, false);
myFileMenu.labelField = "@label"
myFileMenu.addEventListener("itemClick", fileMenuHandler);
myFileMenu.show(fileMenu.x, fileMenu.y + 23);
}

private function fileMenuHandler(event:MenuEvent):void
{
switch (int(event.item.@param))
{
case 1:
fileMenuNew();
break;
case 2:
fileMenuOpen();
break;
case 31:
fileMenuSave("JPEG");
break;
case 32:
fileMenuSave("GIF");
break;
case 4:
fileMenuClose();
break;
default:
break;
}
}

ASファイル内にグローバル変数として以下のように定義します
private var myFileMenu:Menu;


showFileMenu()


[ファイル]ボタンが押された際にshowFileMenu()が実行され、Menuが生成されます
myFileMenu = Menu.createMenu(mainMenuBar, fileMenuList, false);
・ 第1引数は親コンポーネントを指定します
  上記の例では、ApplicationControlBarを親コンポーネントとしています
・ 第2引数はMenuとして表示させたいXMLオブジェクトを指定します
  MXML上にfileMenuListとしてXMLオブジェクトを作成しているので、これを指定しています。
・ 第3引数をtrueにするとXMLオブジェクトのrootから表示されるようになります
  通常は上記のXMLオブジェクトの形式では不要ですので、falseを指定しています


myFileMenu.labelField = "@label"
上記はMenuとして表示させる項目をlabelプロパティにするという指定です


myFileMenu.addEventListener("itemClick", fileMenuHandler);
Menuの中の項目が指定された際にはMenuEvent.ITEM_CLICKイベントが発生します
そのイベントを受け取るリスナーを登録しています


myFileMenu.show(fileMenu.x, fileMenu.y + 23);
showメソッドで実際に画面上に表示させます
この際に表示させる位置を指定することができ、Button:fileMenuの(x,y+23)の位置に表示させるように指定しています


fileMenuHandler


Menu内の項目が選択された時に実行されるメソッドです
event:MenuEventを引数として受け取ります
event.item.@***で選択されたmenuitemのプロパティ値を受け取ることが出来ます
これを利用してparamというプロパティに数値を指定してswitch文で実行するメソッドを選択しています


おまけ


<menuitem label="保存" param="3" enabled="false" >
<menuitem label="JPEGで保存" param="31" />
<menuitem label="GIFで保存" param="32" />
</menuitem>

上記のようにすることにより、保存にマウスがポイントされるとJPEGで・・・の箇所が表示されるようにできます
詳しくはサンプルを見てみてください

スポンサーサイト

Flex3 Flashで画像編集ソフトの作成

Flash上で動く画像編集ソフトの作成


ちょっと時間をかけて(3時間くらい?)作ってみました。
元はこちらの記事のPictureEditor_0_2です


Flash画像編集ソフト


なお、FlashPlayer10でのみ動作します
導入されていない場合にはこちらからインストールしてください


上記リンクから完成例とソースコードが閲覧できます
※ソースコードはzip形式です
なお、あまり需要はないと思いますが、ソースコードのライセンスは[GNU GPL3]とします
そのうちBSDにするつもりです
なお、問い合わせは横のメールフォームからお願いします


画面イメージ


各種機能をポップアップウィンドウで設定するようになっています。
PictureEditor_0_3.gif


機能


  • ローカル画像をロードできる(JPEG,PNG形式)

  • 画像の編集機能は以下の3つ
    1. 画像のリサイズ(nearestNeighborInterpolation:最近隣内挿法)

    2. 画像の2階調化(白・黒だけでなく、好きな閾値で好きな色にできる)

    3. 画像に著作権情報の埋め込み


  • 画像に埋め込んだ著作権情報の読み出し

  • 編集した画像をローカルに保存可能(PNG形式のみ)

注意事項


読み出しボタンは必ず著作権情報を書き込んでからお使い下さい
(ツール→文字情報の書き込み)
特定の画像に関してフリーズするバグがあります


バグメモ


2階調化のポップアップウィンドウで表示される画像サイズがおかしい
付属のPNGEncoderだと72dpiになってしまう
埋め込んだ著作権情報の読み取り時にエラーが発生する
(制御コードのところのアルゴリズムがおかしい)


ソースコードの解説


疲れたから後日…

Flex3 最近隣内挿法での画像のリサイズ

Flex3で最近隣内挿法を実装


FlashPlayer10からローカル資源へのアクセスが可能となりました。
画像の見た目上のサイズはheightプロパティやscaleX,scaleYなどを変更すれば、サイズの変更ができました。
しかし、見た目上のサイズ変更をしただけでは、ローカルに保存する際に元のサイズに戻ってしまいます。
そこで、今回は最近隣内挿法を用いて画像のリサイズを行うメソッドを作成します。


最近隣内挿法とは


非常に単純なアルゴリズムで実装ができます。
また、元画像の情報に変更が加えられないという特徴を持ちます
詳しい解説は「最近隣内挿法」で検索してみてください


実装例


今回は以前から作成している「PictureEditTool.as」にstaticメソッドとして実装します


仕様


仕様は以下の通りです


  1. 引数は3つ
    元となる画像のBitmapDataオブジェクト、変換後の画像の縦サイズ及び横サイズ

  2. サイズ変換されたBitmapDataが返り値となる

ソースコード


以下のような形になります


/** 画像の拡大・縮小関数
* 最近隣内挿法
* @param targetBitmapData ... 拡大・縮小の元となるBitmapData
* @param widthSize ... 変更後のBitmapDataの幅
* @param heightSize ... 変更後のBitmapDataの高さ
* @return BitmapData ... 変更後のBitmapDataオブジェクト
*/
public static function nearestNeighborInterpolation
(targetBitmapData:BitmapData,widthSize:int,heightSize:int):BitmapData
{
// 変更後のオブジェクトの生成
var newBitmapData:BitmapData = new BitmapData(widthSize, heightSize);

// 高さ・幅の比率を取得
var changeScaleX:Number = widthSize / targetBitmapData.width;
var changeScaleY:Number = heightSize / targetBitmapData.height;
//trace("ScaleX : " + changeScaleX + " ScaleY : " + changeScaleY );

// 作成した新たなBitmapDataの全てのピクセルを元データからピクセルを取り出して埋める
for (var y:int = 0; y < heightSize; y++) // Heightのループ
{
for (var x:int = 0; x < widthSize; x++) // Widthのループ
{
// 設置したい箇所に対応するピクセルデータの位置を計算
var targetX:int = int(Math.round( Number(x) / changeScaleX ));
var targetY:int = int(Math.round( Number(y) / changeScaleY ));

// 一応例外処理
if ( targetX >= targetBitmapData.width ) targetX = targetBitmapData.width -1;
if ( targetY >= targetBitmapData.height ) targetY = targetBitmapData.height -1;

// ピクセルデータの埋め込み
newBitmapData.setPixel32( x, y, targetBitmapData.getPixel32( targetX, targetY));
}
}

return newBitmapData;

}

処理フローは以下のようになります


  • 引数で指定された縦サイズ(heightSize),横サイズ(widthSize)のBitmapDataオブジェクトを生成する

  • 元画像と変更後の画像サイズの比率を縦・横共に計算する

  • Forループで縦・横の全てのピクセルにデータを埋め込む

  • 埋め込みたい箇所(x,y)に対応する最も近い元画像データの位置を計算する
    targetX,targetYがx,yに対応する元画像データの位置

  • newBitmapData.setPixel32で画像データを埋め込む
    埋め込み位置は(x,y)で埋め込むデータはtargetBitmapData.getPixel32( targetX, targetY)のデータ

補足
var targetX:int = int(Math.round( Number(x) / changeScaleX ));
上記においてchangeScaleXが2とし、(ようするに元画像を2倍のサイズにする場合)
埋め込むX位置を5とすると5/2で2.5
上をroundで四捨五入すると3となるため、2倍に拡大する場合にX座標が5の位置には元画像のX座標が3のデータが対応することになる


これを使ったサンプルは後日公開します

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