当前位置:  开发笔记 > 编程语言 > 正文

如何使用Flash在ActionScript 3中动态加载渐进式jpeg/jpg,并在完全加载之前知道它的宽度/高度

如何解决《如何使用Flash在ActionScript3中动态加载渐进式jpeg/jpg,并在完全加载之前知道它的宽度/高度》经验,为你挑选了1个好方法。

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

经过大量的测试,我似乎已经找出问题的原因是,直到Loader完全加载jpg,这意味着直到他实际看到jpg的结束字节,他不知道宽度和高度,他不会创建与Loader内容关联的内容DisplayObject.

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

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

谢谢.



1> Didier A...:

我选择了Cay的答案,但我也会回答我自己的问题,补充一些澄清,并告诉其他人我经历过的事情,做错了,最后做得对,以防其他人偶然发现我的问题.

如果要逐步加载jpeg,则需要两件事:URLStream和Loader.然后,您需要按照以下步骤操作:

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

2)您需要向URLStream添加PROGRESS事件处理程序.在该处理程序中,您需要使用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)如果给定的字节不允许显示更多图像,Loader将不会发送完整的事件.因此,除非您想知道jpeg每次传递的加载进度,否则不需要Loader进度事件.

3)在onLoaderComplete中,你可以做任何你想做的事.此时,该活动为您提供了完整的图像.您可以访问loader.content属性.记住,如果不是最后一个Loader完成事件,则意味着它将是您将拥有的CustomActions部分加载图像,因此要么在较低的防御中,要么在其中有一些灰色像素.

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

PS:这是我的大多数代码来自的链接:

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

这里有一些链接实际上通过解析每个字节使用jped规范加载它们来实现自己读取宽度和高度的方法:

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://blog.onebyonedesign.com/?p=71

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有