June 2008
Flexで動的にベクタ画像を表示する方法
- 2008-06-29 (Sun)
- Flash/Flex
Flex3の標準ライブラリでベクタ画像を表示する方法を模索中。 Imageコンポーネントではベクタ画像として唯一SVG形式がサポートされていることをヘルプファイルで発見。 以下のようにhoge.svgを表示しようと試してみるも失敗。
<mx:Image source="hoge.svg"/>
エラーメッセージを読むと、どうやらSVG形式は動的に読み込むことはできず、 最初からSWFファイルに埋め込む形にしなくてはならない。 つまりこのようにする。
<mx:Image source="@Embed('hoge.svg')"/>
こうすると表示できるが、コンパイル時にSWFファイルに埋め込まれる形になる。 つまりユーザの選択に応じて別の画像を表示したりということができない。
ということで、現在の回避策としては以下の方法を取った。
- SVGファイルを埋め込んだSWFファイルを必要数用意しておく
- そのSWFファイルを動的に読み込むようにする
SVGファイルを埋め込んだSWFファイルの作成
まず、以下のようなMXMLファイルを生成してコンパイル。するとSVGファイルが埋め込まれたhoge.swfができる。 今回は3種類のSVGファイルを用意してhoge1.swf, hoge2.swf, hoge3.swfを作成した。
hoge.mxml
<?xml version="1. 0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()">
<mx:Image id="imagebox" source="@Embed('hoge.svg')" y="20" x="20"/>
</mx:Application>
用意したSWFファイルを読み込むMXMLファイルを作成
下記のようにImageコンポーネントのsource属性を動的に変更するようにする。 Listコンポーネントのchangeイベントが発生することでImageコンポーネントのsource属性を変更している。
SVGviewer.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()" alpha="1.0" width="271" height="132">
<mx:HBox x="10" y="10" width="251" height="112">
<mx:Image id="image" width="100" height="100" source="hoge1.swf"/>
<mx:VRule height="106" width="1"/>
<mx:List id="list" width="100" height="81" change="image.source=list.selectedItem.data">
<mx:Object label="hoge1.swf" data="hoge1.swf"/>
<mx:Object label="hoge2.swf" data="hoge2.swf"/>
<mx:Object label="hoge3.swf" data="hoge3.swf"/>
</mx:List>
</mx:HBox>
</mx:Application>
用意したSVG画像が単純すぎてわかりにくいかもしれないけど、このようになる。右側のリストからファイル名を選択すると左側の画像が切り替わる。 判別する術はないかもしれないが、ちゃんとSVG形式のベクタ画像だ。
問題点
現状ではこの方法しか思い浮かばないが、もっといい方法があるかもしれない。 ちなみにこの方法では以下の問題点がある。
画像のファイルサイズが大きくなる
実際今回のサンプルに使用したSVGファイルのサイズは100バイト程度だ。 しかし、SWFファイルにすると250Kバイト程度となり、実に2千倍以上のサイズになっている。 ただし、SVGファイルが大きくなればなるほど、この差は小さくなると思う。
画像毎にMXMLファイルを作成した後、SWFファイルにコンパイルしなくてはならない。
作成するMXMLファイルは定型的なものなので自動化も簡単だが、毎回コンパイルしてファイルを配備する仕組みを作る必要がある。 もちろん、できればそんなことはしたくない。
今回の方法は一つの選択肢ではあるが、引き続き調査は必要だ。
Flex Builder 3を使ってAdobeのチュートリアルを試す #4
- 2008-06-18 (Wed)
- Flash/Flex
Tileコンポーネントの作成
Flickrから取得してきたイメージを表示するためにTileListというコンポーネントを使用する。 HBoxコンポーネントの後、Applicationタグの終了タグの直前に以下の記述を追加しよう。 デザインモードでドラッグ&ドロップした後に編集してもよい。
<mx:TileList width="100%" height="100%"
dataProvider="{photoFeed}">
</mx:TileList>
以下の部分がポイントだと推測できる。前回のエントリーで述べたように、photoFeed変数にはFlickrから取得した結果が何らかの形で格納されている。それをTileList内にこれまたどのような形かで表示するのだろう。前回も述べたとおり、詳細はよくわかっていない。
dataProvider="{photoFeed}"
分かっているのはphotoFeed変数はArrayCollection型ということだけだ。でもそれで十分かもしれない。 そもそもTileListというのは日本語で言えば「タイルを並べたもの」ということなので、dataProvider(データ提供者)に与えたArrayCollectionの中身を一つずつ取って並べて表示するのだろう。
TileListの中にさらに記述を追加していく。 説明はすっ飛ばしてコードだけ見てみよう。
<mx:TileList width="100%" height="100%"
dataProvider="{photoFeed}">
<mx:itemRenderer>
<mx:Component>
<mx:VBox width="125" height="125"
paddingBottom="5"
paddingLeft="5"
paddingTop="5">
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
幅や高さ、余白など見た目の部分はVBoxで設定しているようだ。 それ以外のitemRendererやComponentはどういう働きをしているのかよくわからないが、恐らく概念的に必要なのだろう。我ながら都合のいい解釈だ。
そして最後にVBoxの中に実際の画像とテキストを配置する。 全て記述し終えるとこのようになる。
<mx:TileList width="100%" height="100%"
dataProvider="{photoFeed}">
<mx:itemRenderer>
<mx:Component>
<mx:VBox width="125" height="125"
paddingBottom="5"
paddingLeft="5"
paddingTop="5"
paddingRight="5">
<mx:Image width="75" height="75"
source="{data.thumbnail.url}"/>
<mx:Text text="{data.credit}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
完成!!
セーブしたらメニューより[実行]→[FlickrRIAを実行]を選択し実行してみよう。 うまくいけば、ブラウザが起動するはずだ。検索ワードを入力して検索ボタンを押せばもちろん取得された画像が表示される。 たった54行のソースコードで、しかも一部分はビジュアルエディタで生成したもので、このような見た目も何となく洗練されたアプリケーションができてしまうのだ。 多種多様なコンポーネントを使いこなしたら、相当色んなことができるのではないだろうか。
カスタムコンポーネントを作成し、サムネイル部分を分割する
画像のサムネイル表示部分を別のファイルに分割する。 どうやらカスタムコンポーネントと呼ぶらしい。 そうすることで管理しやすくなる、かどうかは正直わからないが、別のアプリケーションでその部品を再利用できるようになることは確かだ。
メニューより[ファイル]→[新規]→[MXMLコンポーネント]を選択。以下のパラメータで作成する。
- ファイル名 「FlickrThumbnail」
- ベース 「VBox」
- 幅 「125」
- 高さ 「125」
ひな型が自動生成されるため、その内部に先ほど作成したVBoxの中身の部分をコピーする。
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="125" height="125">
<mx:Image width="75" height="75"
source="{data.thumbnail.url}"/>
<mx:Text text="{data.credit}"/>
</mx:VBox>
次にFlickrRIA.mxml内のitemRenderer以下のコンポーネントをバッサリ削除する。 そしてTileListのitemRenderer属性でFlickrThumnailを指定することでFlickrThumnail.mxmlが使用される。
<mx:TileList wi dth="100%" height="100%"
dataProvider="{photoFeed}"
itemRenderer="FlickrThumbnail">
</mx:TileList>
セーブ後、実行して同じように動作すれば成功。 最後にここまでに作成したソースコードを掲載しておく。
FlickrRIA.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundGradientColors="[0xFFFFFF,0xAAAAAA]"
horizontalAlign="left"
verticalGap="15" horizontalGap="15" >
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
[Bindable]
private var photoFeed:ArrayCollection;
private function requestPhotos():void{
photoService.cancel();
var params:Object = new Object();
params.format = 'rss_200_enc';
params.tags = searchTerms.text;
photoService.send(params);
}
private function photoHandler(event:ResultEvent):void{
photoFeed = event.result.rss.channel.item as ArrayCollection;
}
]]>
</mx:Script>
<mx:HTTPService id="photoService"
url="http://api.flickr.com/services/feeds/photos_public.gne"
result="photoHandler(event)"/>
<mx:HBox width="100%">
<mx:Label text="Flickrタグ もしくは検索ワード"/>
<mx:TextInput id="searchTerms"/>
<mx:Button label="検索" click="requestPhotos()"/>
</mx:HBox>
<mx:TileList width="100%" height="100%"
dataProvider="{photoFeed}"
itemRenderer="FlickrThumbnail">
</mx:TileList>
</mx:Application>
FlickrThumbnail.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="125" height="125">
<mx:Image width="75" height="75"
source="{data.thumbnail.url}"/>
<mx:Text text="{data.credit}"/>
</mx:VBox>
お疲れさんっした!!![]()
Flex Builder 3を使ってAdobeのチュートリアルを試す #3
- 2008-06-17 (Tue)
- Flash/Flex
では続けていこう。 今回と次回で完結する予定だ。
HTTPServiceオブジェクトを作成する
「ソース」タブを選択し、ソースコード上のmx:HBoxの上部に以下の記述を追加する。
<mx:HTTPService id="photoService"
url="http://api.flickr.com/services/feeds/photos_public.gne"
result="photoHandler(event)"/>
それぞれの属性値に指定したのは以下のような意味があるはずだ。申し訳ないけど、ここは想像でしかない。 後でこれが間違いだとわかったら修正する。
| 属性名 | 意味 |
|---|---|
| id | このHTTPServiceオブジェクトを保持する変数名 |
| url | 接続するURL |
| result | HTTPリクエストの結果を受け取ったときに実行されるメソッドと引数 |
この時点で画面はこのようになっているはずだ。

ちなみにphotoHandlerというメソッドはまだ作っていないため、この時点では以下のようなエラーがでているが気にしなくていい。 違うエラーメッセージが出ていたら全力で気にするべきだ。
1180: 未定義である可能性が高いメソッド photoHandler の呼び出しです。 FlickrRIA/src FlickrRIA.mxml 行 8
「bindable XML variable in ActionScript 3.0」を作成する
上手い日本語訳が思いつかない。。バインド可能XML変数?組み込みXML変数?まあそんな雰囲気で。
先ほど記述したHTTPServiceコンポーネントの上にもう一つコンポーネントを追加する。
今度はmx:Scriptというもので、どうやらそのコンポーネント内にActionScriptでプログラムを記述するためのものである。
<mx:Script>と打ち込むとコード補完をしてくれて以下のように一気に記述される。
<mx:Script>
<![CDATA[
]]>
</mx:Script>
プログラムは<![CDATA[ と ]]>の間に記述することになる。
これはXMLにおけるコメントを記載するための仕様なのでFlexに限ったことではない。
まずは以下のように必要なクラスを使用できるようにimport宣言を行う。
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
]]>
</mx:Script>
次に検索結果を格納する(変数名から想像するに)変数を宣言する。
[Bindable]という宣言を行うことで、その後のコンポーネントで使用可能になるということであろうか。
詳しくはわからないが、そんなことを気にしていては先に進めないので、とりあえず納得したことにする。
<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
[Bindable]
private var photoFeed:ArrayCollection;
]]>
</mx:Script>
ここまで書くとわかるだろうが、どうやらActionScriptでは変数宣言は以下のようになるみたいだ。
var 変数名:変数の型
検索ボタンのハンドラ作成
引き続きソースコードの編集は続く。 mx:HBox内のmx:Buttonの部分を編集していこう。クリック時のイベントを定義するためにclick属性を追加する。
修正前
<mx:Button label="検索"/>
修正後
<mx:Button label="検索" click="requestPhotos()"/>
これで検索ボタンが押された時にはrequestPhotosというメソッドが実行されるわけだが、このメソッドもまだ実装していないためエラーが出る。
Flickr APIにHTTPリクエストでキーワードを送信する処理の実装
次に検索キーワードを入力するテキストボックスである、mx:TextInputを編集する。 単にidをつけるだけだ。
修正前
<mx:TextInput/>
修正後
<mx:TextInput id="searchTerms"/>
デザインを自分なりに変更してテキストボックスの大きさなどをいじった人はwidth="**"のような属性がある場合もある。
もちろんそれはあっても問題ない。
次に先ほどボタンに定義したハンドラ部分を実装しよう。 mx:Script内に以下のように関数宣言をする。
private function requestPhotos():void{
photoService.cancel();
var params:Object = new Object();
params.format = 'rss_200_enc';
params.tags = searchTerms.text;
photoService.send(params);
}
photoServiceというのはmx:HTTPServiceタグのIDである。Flickrとの通信を制御するHTTPServiceオブジェクトだ。 ボタンが何度も押されたときの対策として、最初の行で現在の通信をキャンセルしているようだ。 その後はparamsというObject型変数にformatとtagsというパラメータをセットしている。 tagsの方にテキストボックスに入力されたテキストを代入している。 先ほどテキストボックスにsearchTermsというid属性を追加したのを憶えているだろうか。 また、formatやtagsというのはおそらくFlickr APIが定義しているパラメータなので、ここでは深くは掘り下げない。 tagsというパラメータに検索ワードを入れるという決まりがあるのだろう。
HTTPService 結果取得ハンドラの実装
Flickrから結果が返ってきたときに実行される処理を記述する。 先ほど書いたrequestPhotos()の後に書こう。 関数名はphotoHandlerとする。 HTTPServiceの宣言部に以下の記載があるためだ。 これにより、HTTPServiceオブジェクトは通信結果を取得するとただちにphotoHandler関数を実行する。
result="photoHandler(event)"
photoHandlerの内容は以下の通りだ。
private function photoHandler(event:ResultEvent):void{
photoFeed = event.result.rss.channel.item as ArrayCollection;
}
Flickrから帰ってきた結果がどのようになっているのかわからないが、ResultEvent型のオブジェクトとして引数のeventに代入される。 そこからコレクションの形でphotoFeedに代入しているようだ。 この辺はFlickr APIやResultEventの仕様がわからなければ詳細はわからない。だから今回は気にしないことにしよう。
学習していく上で大切なことは、今自分が何を学ぼうとしているかを忘れないことだ。 自分が学ぶべき内容と本質的に関係ないものであれば、理解しないまま飛ばしても問題はない。 今回はもちろんFlex Builderの使用法、Flashアプリケーションの作成法を大まかに知ることが重要なので、そちらを優先した。 どうせResultEventの仕様はそのうち嫌でも調べなければいけないことになるだろう。
さて、ここまでのFlickrRIA.mxmlの全体を確認しよう。 足りなかった2つの関数も実装したので今ではエラーもないはずだ。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundGradientColors="[0xFFFFFF,0xAAAAAA]"
horizontalAlign="left"
verticalGap="15" horizontalGap="15" >
<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
[Bindable]
private var photoFeed:ArrayCollection;
private function requestPhotos():void{
photoService.cancel();
var params:Object = new Object();
params.format = 'rss_200_enc';
params.tags = searchTerms.text;
photoService.send(params);
}
private function photoHandler(event:ResultEvent):void{
photoFeed = event.result.rss.channel.item as ArrayCollection;
}
]]>
</mx:Script>
<mx:HTTPService id="photoService"
url="http://api.flickr.com/services/feeds/photos_public.gne"
result="photoHandler(event)"/>
<mx:HBox width="100%">
<mx:Label text="Flickrタグ もしくは検索ワード"/>
<mx:TextInput id="searchTerms"/>
<mx:Button label="検索" click="requestPhotos()"/>
</mx:HBox>
</mx:Application>
次回、いよいよ完成する。
Flex Builder 3を使ってAdobeのチュートリアルを試す #2
- 2008-06-16 (Mon)
- Flash/Flex
途中まで読んで、ようやくプロジェクトの作り方からの説明があった。 どうやらここからがチュートリアルのようだ。 ということで、先ほどインポートしたプロジェクトは無視して進めていくことにする。なんという無計画。
プロジェクトの作成
- [ファイル]→[新規]→[Flexプロジェクト]を選択
- プロジェクト名に「FlickrRIA」と入力してOK
- アプリケーションの種類は「Webアプリケーション(Flash Playerで実行)」を選択
- サーバテクノロジは「なし」を選択
そして終了をクリックすると作成される。
画面フォーマット
プロジェクトを作成するとFlickr.mxmlが開かれる。 左上に「ソース」タブと「デザイン」タブがあるが、まずは「ソース」タブを選択肢、修正する。
修正前
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
</mx:Application>
修正後
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundGradientColors="[0xFFFFFF,0xAAAAAA]"
horizontalAlign="left"
verticalGap="15" horizontalGap="15" >
</mx:Application>
恐らくデザインの修正なので、仮に失敗しても何とかなるだろう、との気軽な感じで次に進めばいいだろう。
デザインモードで検索フォーム作成
そろそろ面白くなってきた。 左上の「デザイン」タブを押して、検索フォームをグラフィカルに作成していく。
左下の「コンポーネント」というビューには、恐らくあらかじめ準備されているFlashの数々のコンポーネントが列挙されている。 その中のレイアウトの下のHBoxをドラッグ&ドロップで画面上に持っていくと、ポップアップが現れて表示サイズを聞いてくるので、そのままOKボタン。


たったこれだけ。 まあ、そうだろうなと予測はしていたけど、なんと嬉しいことか。 正直言ってアプリケーション作る時は、大抵頭の中には作りたいものが具体的にあって、その作り方もかなり細かいレベルでイメージしている。 後は手を動かすだけなんだけど、その手を動かす時間が煩わしくてしかたがないわけだ。 思考のスピードに手のスピードがついてくるはずなどないのだけど、こういうGUIビルダーというのは考えうる現実の解の中ではやはり最適だと思う。 ブラウザアプリケーションの世界にももっと普及すべきだ。 僕が知らないだけで普及しているのだろうか?
次はコントロールの下のLabelを先ほど作成したHBoxの領域にドラッグ&ドロップ。 そのラベルの中をダブルクリックしてラベルの文字列を編集する。 Adobeのチュートリアルではラベルの文字列も英語なので、なんとなくオレ日本語に翻訳してみよう。


同じくコントロールの下のTextInputをHBoxの領域内にドラッグ&ドロップ。 ラベルの右側に配置する。 さらにその右側に同じくコントロール下のButtonを配置し、ボタンの文字列を「検索」というオレ日本語に変更する。 以下のようになったはずだ。

一度「ソース」タブを選択してどうなったか見てみよう。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundGradientColors="[0xFFFFFF,0xAAAAAA]"
horizontalAlign="left"
verticalGap="15" horizontalGap="15" >
<mx:HBox width="100%">
<mx:Label text="Flickrタグ もしくは検索ワード"/>
<mx:TextInput/>
<mx:Button label="検索"/>
</mx:HBox>
</mx:Application>
mx:HBoxという領域内にmx:Label、mx:TextInput、mx:Buttonが配置されているのがわかるはずだ。デザインのほうでサイズなどを変更すればソース上でwidthなどの属性として反映されるようになっている。適宜画面を見ながら好きなように変更してもよい。
では次回はFlickrに接続する部分の処理を実装していく。
Flex Builder 3を使ってAdobeのチュートリアルを試す #1
- 2008-06-15 (Sun)
- Flash/Flex
もうそろそろFlashに手を出しておかなければいけないだろうと感じ、Flex Builder 3のデモ版を入手した。
インストールはごく普通。ここでも参考にすればいいでしょう。 ちなみに今は日本語版があるのでそちらをダウンロードすることをお勧めします。
Flex/AIRの開発環境Flex Builder 3を使ってみよう
こちらのチュートリアルを参考にすることにした。英語なのが辛いところ。
前置きが続くので2ページほど飛ばすと、突然コードが出てきた。 どこにどのように入力するのかは全く説明されていない。 ベースはEclipseなので、ある程度の使い方はわかるのだが、いくらなんでもこれじゃどうしていいのかわからない。
ということで、このチュートリアルのソースコードをダウンロードすることにした。 ダウンロードはこちら。 「Building a simple RIA」というリンクからzipファイルをダウンロードできる。
Download preconfigured Flex Builder projects
以下のように[ファイル]→[インポート]→[Flexプロジェクト]でファイル選択画面へ。

アーカイブファイルにダウンロードしたzipファイルを指定すると、そのままインポートできた。
プロジェクト直下にある2つのmxmlファイル(FlickrRIA.mxml、FlickrThumbnail.mxml)がこのプロジェクトの主要な部分みたいだ。 とりあえず走らせてみる。 [実行]→[FlickrRIAを実行]でブラウザが起動し、このアプリケーションが表示される。

検索窓に適当なキーワードを入れて検索するとFlickrから検索してくる。 (海外ユーザのタグを検索するようなので、英語で入力しましょう。)

※豆知識
マキシマムザホルモンは海外でCDを発売していないにも関わらず、海外にコアなファンやコピーバンドがたくさんいるのです。
ではコード内容の解析は#2で。