Actionscript 3 如何在Flex中显示文件流的保存进度?
我正在制作一个简单的工具,让用户最终将图像保存到磁盘上。 为此,我使用了Actionscript 3 如何在Flex中显示文件流的保存进度?,actionscript-3,apache-flex,file-io,asynchronous,progress,Actionscript 3,Apache Flex,File Io,Asynchronous,Progress,我正在制作一个简单的工具,让用户最终将图像保存到磁盘上。 为此,我使用了FileStream类及其writeBytes()方法 这工作得很好。当我试图用一个简单的mx:ProgressBar显示保存进度时,出现了问题。我试过一些方法,但似乎都不管用 下面是ActionScript的一段代码: private function save(file:File, image:MyImageClass):void { var data:BitmapData = new BitmapData(wi
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"/>
执行此操作时,我得到了一个冻结的接口,当文件完全保存时,该接口被释放,并且在控制台上我同时获得了所有跟踪。进度条保持在0%,直到界面解冻并变为100%
我知道Flash是单线程的,但我认为FileStream.openAsync()
方法应该做一些肮脏的工作,让我的接口负责。完成这项简单且(我认为)普通的任务应该不会那么难
问题是:我做错了什么
提前感谢正在保存的文件有多大 就保存文件而言,您的代码似乎很好。然而,我怀疑实际需要很长时间的是将文件编码为PNG格式。不幸的是,
PNGEncoder
没有发送任何进度事件。但是你应该检查一下,或者考虑使用ActionScript工作人员在不同的线程中进行编码。
快速证明方法:在编码到PNG之前/之后添加跟踪语句。大延迟是对应于此阶段,还是对应于实际保存
如果这没有帮助,请指定文件的大小,以及您是获得0、1还是多个输出进度事件。要保存的文件有多大 就保存文件而言,您的代码似乎很好。然而,我怀疑实际需要很长时间的是将文件编码为PNG格式。不幸的是,
PNGEncoder
没有发送任何进度事件。但是你应该检查一下,或者考虑使用ActionScript工作人员在不同的线程中进行编码。
快速证明方法:在编码到PNG之前/之后添加跟踪语句。大延迟是对应于此阶段,还是对应于实际保存
如果这没有帮助,请指定文件的大小,以及您是获得0、1还是多个输出进度事件。我同意Sunil,但我想补充一两件事 首先,我建议使用
BitmapData
类的新方法对图像进行编码,因为它更快更容易。因此,您的代码将更改为以下内容:
var data:BitmapData = new BitmapData(width, height, true, 0x000000);
image.draw(data, _cols);
var bytes:ByteArray = data.encode(data.rect, new PNGEncoderOptions());
bytes.position = 0;
while(bytes.bytesAvailable > 0) {
fileStream.writeByte(bytes.readByte());
trace("progress:", bytes.position / bytes.length * 100); // multiply by 100 for percentage
}
您可以跟踪文件的编写进度(尽管我怀疑这不会花费太多时间,正如Sunil所说),如下所示:
var data:BitmapData = new BitmapData(width, height, true, 0x000000);
image.draw(data, _cols);
var bytes:ByteArray = data.encode(data.rect, new PNGEncoderOptions());
bytes.position = 0;
while(bytes.bytesAvailable > 0) {
fileStream.writeByte(bytes.readByte());
trace("progress:", bytes.position / bytes.length * 100); // multiply by 100 for percentage
}
请注意,这种方法需要一名工作人员,否则只有在保存完成后,进度才会直观地更新。我同意Sunil的观点,但我想补充一两点 首先,我建议使用
BitmapData
类的新方法对图像进行编码,因为它更快更容易。因此,您的代码将更改为以下内容:
var data:BitmapData = new BitmapData(width, height, true, 0x000000);
image.draw(data, _cols);
var bytes:ByteArray = data.encode(data.rect, new PNGEncoderOptions());
bytes.position = 0;
while(bytes.bytesAvailable > 0) {
fileStream.writeByte(bytes.readByte());
trace("progress:", bytes.position / bytes.length * 100); // multiply by 100 for percentage
}
您可以跟踪文件的编写进度(尽管我怀疑这不会花费太多时间,正如Sunil所说),如下所示:
var data:BitmapData = new BitmapData(width, height, true, 0x000000);
image.draw(data, _cols);
var bytes:ByteArray = data.encode(data.rect, new PNGEncoderOptions());
bytes.position = 0;
while(bytes.bytesAvailable > 0) {
fileStream.writeByte(bytes.readByte());
trace("progress:", bytes.position / bytes.length * 100); // multiply by 100 for percentage
}
请注意,这种方法需要一名工作人员,否则只有在保存完成后,进度才会直观地更新。Sunil是正确的。写这个文件几乎不需要花一点时间。它正在解码阻止应用程序的字节数组。我实现了以下代码来测试它
private function save(file:File):void
{
var bytes:ByteArray = new ByteArray();
//233348 - very fast (requires 6000 x 10000 bitmap pixels)
//252790 - very fast (requires 6500 x 10000 bitmap pixels)
//2488990 - need a whole magnitude more of data in order to show the progress messages
for (var i:int = 0; i < 2488990; i++)
{
bytes.writeByte(1);
}
var fileStream: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();
}
}
私有函数保存(文件:文件):无效
{
变量字节:ByteArray=newbytearray();
//233348-非常快(需要6000 x 10000位图像素)
//252790-非常快(需要6500 x 10000位图像素)
//2488990-需要更多的数据才能显示进度消息
对于(变量i:int=0;i<2488990;i++)
{
字节。写入字节(1);
}
var fileStream:fileStream=newfilestream();
fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS,onProgress);
addEventListener(Event.CLOSE,onClose);
试一试{
openAsync(文件,FileMode.WRITE);
fileStream.writeBytes(字节);
}捕获(e:错误){
//Alert.show(“尝试保存图像时出错:+e.message”);
}最后{
fileStream.close();
}
}
您需要在解码任务上使用进度指示器,而不是在文件写入任务上使用进度指示器。Workers似乎是解决这一问题的最佳解决方案,但这取决于您需要以哪个版本的运行时为目标。Sunil是正确的。写这个文件几乎不需要花一点时间。它正在解码阻止应用程序的字节数组。我实现了以下代码来测试它
private function save(file:File):void
{
var bytes:ByteArray = new ByteArray();
//233348 - very fast (requires 6000 x 10000 bitmap pixels)
//252790 - very fast (requires 6500 x 10000 bitmap pixels)
//2488990 - need a whole magnitude more of data in order to show the progress messages
for (var i:int = 0; i < 2488990; i++)
{
bytes.writeByte(1);
}
var fileStream: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();
}
}
私有函数保存(文件:文件):无效
{
变量字节:ByteArray=newbytearray();
//233348-非常快(需要6000 x 10000位图像素)
//252790-非常快(需要6500 x 10000位图像素)
//2488990-需要更多的数据才能显示进度消息
对于(变量i:int=0;i<2488990;i++)
{
字节。写入字节(1);
}
var fileStream:fileStream=newfilestream();
fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS,onProgress);
addEventListener(Event.CLOSE,onClose);
试一试{
openAsync(文件,FileMode.WRITE);
fileStream.writeBytes(字节);
}捕获(e:错误){
//Alert.show(“尝试保存图像时出错:+e.message”);
}最后{
fileStream.close();
}
}
您需要在解码任务上使用进度指示器,而不是在文件写入任务上使用进度指示器。Worker似乎是解决这一问题的最佳方案,但这取决于您需要以哪个版本的运行时为目标。只是一个更正;Flash播放器不是单线程的。虽然他们不给progra