gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 14:21:01 27 4
gpt4 key购买 nike

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

经过大量测试,我似乎找到了问题的原因,直到Loader完全加载jpg,这意味着直到他真正看到jpg的末尾字节,他才知道宽度和高度,他不创建与加载程序的内容相关联的内容 DisplayObject。

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

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

谢谢你。

最佳答案

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

如果你想逐步加载一个 jpeg,你需要两个东西:一个 URLStream 和一个加载器。然后您需要按照以下步骤操作:

1) 您必须使用 URLStream 将 jpeg 从 URLRequest 加载到 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 progress事件,除非你想知道jpeg的每一个pass的加载进度。

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

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

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

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

关于flash - 如何使用 Flash 在 ActionScript 3 中动态加载渐进式 jpeg/jpg 并在完全加载之前知道它的宽度/高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1814833/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com