1

ユーザーが最終的にイメージをディスクに保存できるようにする簡単なツールを作成しています。これを行うために、FileStreamクラスとそのwriteBytes()メソッドを使用しています。

これはうまく機能しています。この問題は、保存の進行状況を単純なmx:ProgressBar. いくつかのアプローチを試しましたが、どれもうまくいかないようです。

ActionScript のコードは次のとおりです。

private function save(file:File, image:MyImageClass):void {
    var data:BitmapData = new BitmapData(width, height, true, 0x000000);
    image.draw(data, _cols);
    var bytes:ByteArray = new PNGEncoder().encode(data);
    fileStream = new FileStream();
    fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, onProgress);
    fileStream.addEventListener(Event.CLOSE, onClose);
    try {
        fileStream.openAsync(file, FileMode.WRITE);
        fileStream.writeBytes(bytes);
    } catch (e:Error) {
        Alert.show("Error trying to save the image: " + e.message);
    } finally {
        fileStream.close();
    }
}

private function onProgress(event:OutputProgressEvent):void {
    var progressRatio:Number = (1 - (event.bytesPending / event.bytesTotal));
    progressBar.setProgress(progressRatio, 1);
    trace(progressRatio);
    if (event.bytesPending == 0)
        event.target.close();
}

private function onClose(event:Event):void {
    trace("closed");
}

進行状況バーの mxml:

<mx:ProgressBar id="progressBar" mode="manual"/>

これを実行すると、ファイルが完全に保存されたときに解放されるフリーズしたインターフェイスが得られ、コンソールですべてのトレースが同時に取得されます。プログレス バーは、インターフェイスがフリーズして 100% になるまで 0% のままです。

Flash がシングル スレッドであることは知っていますがFileStream.openAsync()、インターフェイスを責任あるものにするために、メソッドが汚い作業を行う必要があると考えました。この単純で (私が思うに) 一般的なタスクを実行するのはそれほど難しいことではありません。

問題は、私が間違っていることは何ですか?

前もって感謝します

4

3 に答える 3

1

私は Sunil に同意しますが、1 つまたは 2 つのことを追加したいと思います。

まず第一にBitmapData、画像をエンコードするクラスの新しいメソッドを使用することをお勧めします。これは、高速で簡単だからです。したがって、コードは次のように変更されます。

var data:BitmapData = new BitmapData(width, height, true, 0x000000);
image.draw(data, _cols);
var bytes:ByteArray = data.encode(data.rect, new PNGEncoderOptions());

次のように、ファイルの書き込みの進行状況を追跡できます(Sunilが言ったように、これにはそれほど時間がかからないと思いますが):

bytes.position = 0;
while(bytes.bytesAvailable > 0) {
    fileStream.writeByte(bytes.readByte());
    trace("progress:", bytes.position / bytes.length * 100); // multiply by 100 for percentage
}

このアプローチにはワーカーが必要であることに注意してください。そうしないと、保存が完了したときに進行状況が視覚的に更新されるだけです。

于 2013-07-05T08:31:06.590 に答える