如何使用 Flash 在 ActionScript 3 中动态加载渐进式 jpeg/jpg 并在完全加载之前了解其宽度/高度

2023-12-27

我正在尝试使用 ActionScript 3 动态加载渐进式 jpeg。为此,我创建了一个名为 Progressiveloader 的类,该类创建 URLStream 并使用它将渐进式 jpeg 字节流式加载到 byteArray 中。每次 byteArray 增长时,我都会使用 Loader 来加载 byteArray。这在某种程度上有效,因为如果我 addChild 加载器,我可以看到流式传输的 jpeg,但我无法访问加载器的内容,最重要的是,我无法更改加载器的宽度和高度。

经过大量测试,我似乎已经弄清楚问题的原因是,在Loader完全加载jpg之前,这意味着直到他真正看到jpg的结束字节之前,他不知道宽度和高度,并且他不创建与加载程序的内容关联的内容 DisplayObject。

我的问题是,有没有办法在加载 jpeg 之前实际知道它的宽度和高度?

P.S.:我相信这是可能的,因为渐进式 jpeg 的性质,它会加载到完整尺寸,但细节较少,因此应该知道尺寸。即使以这种方式加载普通 jpeg,尺寸也会在屏幕上看到,除了尚未加载的像素显示为灰色。

谢谢。


我选择了凯的答案,但我也会回答我自己的问题,以添加一些说明,并告知其他人我经历过的事情、做错的事以及最终做对的事情,以防其他人偶然发现我的问题。

如果你想逐步加载 jpeg,你需要两个东西:URLStream 和 Loader。然后您需要执行以下步骤:

1) 您必须使用 URLStream 将 URLRequest 中的 jpeg 加载到 ByteArray 中。

2) 您需要将 PROGRESS 事件处理程序添加到 URLStream。在该处理程序中,您需要使用 Loader 来 loadBytes() URLStream 新加载的字节。

3)您需要一个 Loader COMPLETE 事件处理程序来访问加载的 jpeg 的每个通道并对其执行任何您想要的操作,例如显示它或调整它的大小等。

4) 您需要一个 URLStream COMPLETE 事件处理程序来确保所有字节都已加载,并在您自己之后进行清理并关闭流。

var urlStream:URLStream = new URLStream(); //We will use this to progressively stream the bytes of the jpeg
var byteArray:ByteArray = new ByteArray(); //Bytes from the URLStream will go here
var loader:Loader = new Loader(); //We will use this Loader to load the bytes from the ByteArray
var url:String = "http://myAddressToMyJpeg.jpg"; //The url to the jpeg

urlStream.load(new URLRequest(url));

urlStream.addEventListener(ProgressEvent.PROGRESS, onStreamProgress, false, 0, true);
urlStream.addEventListener(Event.COMPLETE, onStreamComplete, false, 0, true);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete, false, 0, true);

function onStreamProgress(evt:ProgressEvent):void
{
    // You could put a condition here to restrain the number of calls to updateBytes().
    // Use the evt.bytesTotal and evt.bytesLoaded to help accomplish this.
    // You will find that by limiting it, it will increase responssivness of your
    // program and give an overall better result.
    // Have it call updateBytes() every 100 bytes or so.
    updateBytes();
}

function onStreamComplete(evt:Event):void
{
    updateBytes(); // Call updateBytes one more time to load in the last bytes.

    urlStream.removeEventListener(ProgressEvent.PROGRESS, onStreamProgress); // Clean after yourself
    urlStream.removeEventListener(Event.COMPLETE, onStreamComplete); // Clean after yourself

    // Somehow, without this, it does not work. You will end up with a ~90% loaded image
    setTimeout(confirmBytesLoaded,500); // Would be nice if someone could tell me why this makes it work!!
}

function confirmBytesLoaded():void
{
    updateBytes(); // As said earlier, you need to check it one last time it seems.
    if (urlStream.connected) urlStream.close(); // Close the stream once you're done with it.
}

function updateBytes():void
{
    // Important step. We copy the bytes from the stream into our byteArray,
    // but we only want to add the new bytes to our byteArray, so we use the lenght
    // attribute as an offset so that the new bytes gets added after the bytes that we added before.
    urlStream.readBytes(byteArray, byteArray.length);

    if(byteArray.length > 0) // Make sure there are new bytes to load.
    {
        loader.loadBytes(byteArray); // Use the Loader to decode the loaded bytes.
    }
}

// onLoaderComplete will be called many times.
// Every time there is enough new bytes to diplay more of the image
// onLoaderComplete will be called. So for every pass of the jpeg one
// this will be called.
function onLoaderComplete(evt:Event):void
{   
    // bm will now contain the bitmapData of the progressively loaded jpeg.
    var bm:Bitmap = Bitmap(loader); // We make a bitmap object from the loader.

    bm.width = 400; // Because my goal was to be able to resize the image as it is loaded and display it :).
    bm.height = 400; // Because my goal was to be able to resize the image as it is loaded and display it :).
    addChild(bm); // See the result for yourself...
}

整个过程的一些注意事项:

1)confirmBytesLoaded 是您了解图像何时完全加载的队列。

2) 如果给定的字节不允许显示更多图像,则加载器将不会调度完整事件。因此,除非您想了解 jpeg 每一遍的加载进度,否则不需要 Loader Progress 事件。

3)在onLoaderComplete中你可以做任何你想做的事情。此时,该事件将为您提供一个可以使用的完整图像。您可以访问 loader.content 属性。请记住,如果不是最后一个加载程序完成事件,则意味着您将拥有的是 CustomActions 部分加载的图像,因此要么是较低的分辨率,要么是其中包含一些灰色像素。

4) 当您使用 loadBytes 时,它会在您的应用程序上下文中加载图像。因此,请确保仅以这种方式加载受信任的内容。我还不确定是否有办法解决这个问题,以确保其安全。看:http://onflash.org/ted/2008/01/loaderload-vs-loaderloadbytes.php http://onflash.org/ted/2008/01/loaderload-vs-loaderloadbytes.php

附: 这是我的大部分代码来自的链接:

http://orangeflash.eu/?p=13 http://orangeflash.eu/?p=13

以下是一些链接,它们实际上向您展示了一种通过解析使用 jped 规范加载的每个字节来自己读取宽度和高度的方法:

http://www.anttikupila.com/flash/getting-jpg-dimensions-with-as3-without-loading-the-entire-file/ http://www.anttikupila.com/flash/getting-jpg-dimensions-with-as3-without-loading-the-entire-file/

http://www.emstris.com/2009/05/extracting-binary-info/ http://www.emstris.com/2009/05/extracting-binary-info/

http://blog.onebyonedesign.com/?p=71 http://blog.onebyonedesign.com/?p=71

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Flash 在 ActionScript 3 中动态加载渐进式 jpeg/jpg 并在完全加载之前了解其宽度/高度 的相关文章

随机推荐