[AS3] 複数画像を非同期で順にロードしていくImageLoadQueue(イメージロードキュー)クラス

Categorie:{ actionscript } Tag:{, } Comments:{ No Comments }
Posted:{ 2010.10.01 04:29:51 }

複数画像を非同期で順にロードしていくImageLoadQueueクラス(AS3)を公開します。

※追記 ドキュメントをアップしました。ImageLoadQueue ASDoc

こんな時に

大量画像ロード時、一気にロードすると高負荷になるので、非同期で1つづつLoadしたい時など。
例えば、
・背景に多くの画像がスライド、ループするような演出。
・画像の検索結果を表示し(ロード完了を待たずに)次々とページ送り出来るようなUI。
・さまざまな階層で同じ画像を何度も読み込むようなサイト。
など。

特徴

1.(シングルトンなので)どの階層からでも、キューに追加でき、読み込まれた画像はグローバルに保管されどこからでも取得できる
2.途中ロードエラーが起きてもスキップして順次ロードする(どのURLでエラーが起きたか取得可能)
3.ロード完了時、コンプリートリスナ関数に「画像のコピー」を返す(グローバルに保管された画像は変更されない)
4.ロード完了済URLをadd()した場合、保管された画像のコピーがコンプリートイベントで返される。
5.同じURLを複数add()した場合、登録された全てのリスナー関数が同時実行される。
(例えばhoge.jpgを3回add()すると、1番目がロード完了後、3つのコンプリートリスナー関数が同時実行される)
6.任意のタイミングでロードストップできる。

サンプルデモ

http://www.romatica.com/dev/imageloadqueue/sample/ImageLoadQueueSample.swf
・意図的に2枚の画像をロードエラーにし、スキップ機能の確認をしています。(※上記2.)
・6枚目と最後は同じ画像をキューに追加しているので、6枚目が読まれた時点で、最後の画像も完了処理がされます。(※上記5.)
※追記 デモのソースをアップしました(上記URLとは若干内容が異なります)

使い方(基本)

まずimport文を記述

1
2
import com.romatica.loader.ImageLoadQueue;
import com.romatica.events.ImageLoadQueueEvent;

シングルトンなので、new せずに「ImageLoadQueue.getInstance()」でインスタンスを取得します。

1
2
3
4
   var _imageLoadQueue:ImageLoadQueue
〜略〜
  _imageLoadQueue = ImageLoadQueue.getInstance();
  _imageLoadQueue.debug = !true;//状況をトレース確認したい場合true

ロードキューに追加する場合、add()メソッド

  • イメージURL
  • コンプリートリスナ関数
  • プログレスリスナ関数  (省略可)
  • URLオープンリスナ関数 (省略可)
  • エラーリスナ関数    (省略可)

を登録し、load()で実行します。
※add()もload()も好きなタイミングで何度でも実行できます

1
2
3
4
5
6
_imageLoadQueue .add("images/1.png",onComplete);
_imageLoadQueue .add("images/2.png",onComplete,onProgress);
_imageLoadQueue .add("images/3.png",onComplete,onProgress,onOpen,onError);
_imageLoadQueue .load();
_imageLoadQueue .add("images/4.png",onComplete2,onProgress2);
_imageLoadQueue .load();

イベントはImageLoadQueueEventが返ってきます。
イベントのプロパティにいろいろ入っています。
※例えばコンプリートにはevent.bitmapData プログレスには event.percent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//ロード完了 
private function onComplete(event:ImageLoadQueueEvent):void{
	//eventのプロパティに url とbitmapData があります。
	 trace("[complete] "+event.url)
	 var bm:Bitmap = addChild(new Bitmap(event.bitmapData)) as Bitmap;
	 bm.x = Math.random()*300;
	 bm.y = Math.random()*300;
 }
//ロードプログレス
private function onProgress(event:ImageLoadQueueEvent):void{
	 //ロードパーセントもevent.percentで取得できます。
	 trace("[progress] "+event.url +"/"+event.bytesLoaded+"/"+event.bytesTotal+"/"+event.percent+"%")
 }
//ロードが開始された
private function onOpen(event:ImageLoadQueueEvent):void{
	 trace("[open] "+event.url )
 }
//ロードエラー
 private function onError(event:ImageLoadQueueEvent):void{
	 trace("[error] "+event.url +"/"+event.text)
 }

キューから削除もしくは、ロードストップしたい場合は
_imageLoadQueue.stop(url)します。

使い方(応用1)

と、ここまでならなんの変哲もないですが、このクラスは、どの階層からも非同期で読み込み出来るのが特徴です。
例えば、さまざまな任意階層にImageWrapperなどのクラスを多数作り、コンストラクタにURLを渡してgetInstance()し、任意のタイミングでload()、stop()するなどの使い方ができます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//ex)ImageWrapper.as
   //コンストラクタ
    public function imageWrapper(url : String){
         _url =url;
         _imageLoadQueue = ImageLoadQueue.getInstance();//ImageLoadQueueインスタンス取得
    }
   /**ロードスタート*/
   public function load():void{
	_imageLoadQueue.add( _url, compFunc , onProgress, onOpen,onError );
	_imageLoadQueue.load();
   }
   /**ロードストップ 読み込み前、もしくは読み込み中をキャンセルする*/
   public function stop():void{
	_imageLoadQueue.stop(_url);
   }
   private function onError(event : ImageLoadQueueEvent) : void{/*任意の処理*/}
   private function onOpen(event:ImageLoadQueueEvent):void{/*任意の処理*/}
   private function onProgress(event : ImageLoadQueueEvent) : void{/*任意の処理*/}
   private function compFunc(event : ImageLoadQueueEvent):void{/*任意の処理*/}

くどいですがつまり、どの階層(クラス)からでも、キューを出せ、完了したタイミングでどの階層にでも画像を返してもらう事が出来ます

使い方(応用2)

その他のメソッドとして
allStop() 全てのロードを停止
allClear() 全てのロードを停止し、ロードされた画像を全てdispose()
があります。

例えば、利用シーンとして、「画像一覧ページで必要画像をキューに追加しload()した直後、ロード完了を待たずに、ユーザーがページ送りしたらallStop()でキューを停止し、次の一覧ページへ移動する。
など必要最小限のロード処理で、負荷を抑えたサイト実装が出来ます。

ソースダウンロード

zipで取得したい方はこちら(サンプルデモと同じデータ)
Sparkにコミットしましたので、SVNで取得したいかたはこちらからどうぞ。
http://www.libspark.org/browser/as3/Romatica/ImageLoadQueue

その他

Progressionを使っているなら「LoaderList コマンド」or 「ResourcePrefetcher クラス」で似たようなことが簡単にできるかもしれませんが、Progressionを使わない場合は役立つ?かも。

まだまだソースも整理されていなくて、バグなどもあるかもしれませんので今後、改善していく予定です。
バグ発見された方は報告いただけるとありがたいです。(・∀・)

※追記エントリを書きました。
[as3]ImageLoadQueueクラスドキュメントとサンプルコードアップ

関連記事

Comment


レンタルサーバー豆知識