— boreal-kiss.com

FileReference.loadで画像を読み込むとイメージプロパティがわからず超不便(解決済み)

[追記:2008/05/27]

解決しました。Loader.loadBytesのイベント取得前にプロパティにアクセスしようとしていたことが原因でした。記事最下部に新たに修正コードを載せておきます。

Flash Player 10から、FileReference.loadでローカルにあるファイルをFlash Playerにロードできるようになった。ただしFileReference.loadでロードしたデータは必ずバイナリ形式になるので、画像データを読み込ませたいときには一工夫必要。以下の例のようにLoader.loadBytesを使わなければいけない。([追記:2008/05/27]記事最下部に修正版があるのでそちらを参照ください)

import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.FileReference;

var _fr:FileReference = new FileReference();
stage.addEventListener(MouseEvent.CLICK,onClick);
_fr.addEventListener(Event.SELECT,onSelect);
_fr.addEventListener(Event.COMPLETE,onComplete);
        
function onClick(e:Event):void{
    _fr.browse();
}

function onSelect(e:Event):void{
    var f:FileReference = FileReference(e.target);
    f.load();
}
        
function onComplete(e:Event):void{
    var f:FileReference = FileReference(e.target);
    var loader:Loader = new Loader();
    loader.loadBytes(f.data);
    addChild(loader);
}

ところで、Load.loadBytesで読み込むとLoaderは元画像のwidthなんかのプロパティ情報を保持しなくなる。上の例で画像を読み込ませてloaderの中身を見てみると以下のようになる。

trace(loader.content);//null
trace(loader.contentLoaderInfo);//[object LoaderInfo]
trace(loader.contentLoaderInfo.content);//null
trace(loader.contentLoaderInfo.content.width);//Error: no such properties!!

Loader.content、Loader.contentLoaderInfo.contentともに存在しない。”プロパティが存在しない”というこの性質を利用するとFlash Playerの制限を超えるサイズの画像もロードできるみたいだけど(void element blog: 2880pxよりも大きい画像を読み込む方法を発見したよ)、読み込んだ画像のサイズがわからんのでは扱いに困る。ユーザーの好きなサイズのファイルをローカルからロードできるところが面白いのに。どんな寸法の画像をロードされても例えばステージ中心に配置するにはどうすればいいのかね。

[追記:2008/05/27]

FileReference.loadで画像を読み込んでイメージプロパティを取得するまでの修正コード。

import flash.display.Loader;
import flash.display.Bitmap;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.FileReference;

var _fr:FileReference = new FileReference();
stage.addEventListener(MouseEvent.CLICK,onClick);
_fr.addEventListener(Event.SELECT,onSelect);
_fr.addEventListener(Event.COMPLETE,onComplete);

function onClick(e:Event):void{
    _fr.browse();
}

function onSelect(e:Event):void{
    var f:FileReference = FileReference(e.target);
    f.load();
}

function onComplete(e:Event):void{
    var f:FileReference = FileReference(e.target);
    var loader:Loader = new Loader();
    loader.loadBytes(f.data);
    
    //It's too early!!
    //addChild(loader);
    loader.contentLoaderInfo.addEventListener(Event.INIT,init);
}

//Add the image at the stage center
function init(e:Event):void{
    trace(e.target.content);//[object Bitmap]
    var bmp:Bitmap = Bitmap(e.target.content);
    bmp.x = stage.stageWidth/2 - bmp.width/2;
    bmp.y = stage.stageHeight/2 - bmp.height/2;
    addChild(bmp);
}

追記 2008/10/19

Filereferenceオブジェクトの参照方法について補足。参照している変数が(全て)スコープ範囲外に移動すると、FileReference.load()などの一部のメソッドは途中キャンセルされる。詳しくはFileReferenceオブジェクトと変数のスコープの関係 – boreal-kiss.comを参照ください。

4 comments
  1. yossy:beinteracctive says: 2008年5月27日10:40 AM

    未検証で申し訳ないですが、 contentWidth プロパティで取得出来ませんか?

  2. admin says: 2008年5月27日5:35 PM

    描画準備前にプロパティにアクセスしていたのが原因でした。お騒がせしました。

  3. yossy:beinteracctive says: 2008年5月27日6:04 PM

    おお、なるほど。
    ここ、イベント待ちしなきゃいけないのが分かりにくいですよね。

  4. […] FileReference.loadで画像を読み込むとイメージプロパティがわからず超不便(解… […]

Submit comment