Did*_* A. 6 flash actionscript-3
我正在尝试使用ActionScript 3动态加载渐进式jpeg.为此,我创建了一个名为Progressiveloader的类,它创建一个URLStream并使用它将渐进式jpeg字节流加载到byteArray中.每次byteArray增长时,我都使用Loader来加载byteArray.这在某种程度上是有效的,因为如果我addChild加载器,我能够看到jpeg流式传输,但我无法访问Loader的内容,最重要的是,我无法更改Loader的宽度和高度.
经过大量的测试,我似乎已经找出问题的原因是,直到Loader完全加载jpg,这意味着直到他实际看到jpg的结束字节,他不知道宽度和高度,他不会创建与Loader内容关联的内容DisplayObject.
我的问题是,有没有办法在加载之前真正知道jpeg的宽度和高度?
PS:我相信这是可能的,因为渐进式jpeg的性质,它被加载到它的全尺寸,但细节较少,因此应该知道大小.即使以这种方式加载普通的jpeg,也可以在屏幕上看到大小,除了尚未加载的像素显示为灰色.
谢谢.
Did*_* A. 10
我选择了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...
}
Run Code Online (Sandbox Code Playgroud)
关于整个过程的一些注意事项:
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:这是我的大多数代码来自的链接:
这里有一些链接实际上通过解析每个字节使用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
我认为你的问题是 loadBytes 是异步的......这意味着你需要等到“完成”事件才能检索(或更改)其宽度和高度......我的意思是:
var loader:Loader=new Loader();
loader.loadBytes(myBytes);
trace(loader.width, loader.contentLoaderInfo.width); //will always output zero
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);
function imgLoaded(e) {
trace(loader.width, loader.height); //will output the loader dimensions
trace(loader.contentLoaderInfo.width, loader.contentLoaderInfo.height); //will always output the original JPEG dimensions
}
Run Code Online (Sandbox Code Playgroud)