无论Content-Type如何,Flash / AS3都可以加载外部图像吗?

时间:2011-06-21 00:27:18

标签: flash actionscript-3

  

免责声明:我不是Flash开发人员   但我正试图解决一个闪光问题。   请不要以为我是亲密的   熟悉AS或Flash,因为我   不

我目前面临的困境是我正在托管application/octet-stream资源。在我的Actionscript代码中,我正在使用一些库(我可以记得)new Image并将资源加载到已创建的对象中。

有一种方法,loadImage(url)接受一个网址,您可以在其中提供图片的路径。

我无法访问loadImage源代码,所以我不确切知道它的作用,但是正常工作的图片加载图片时因为Content-Typeimage/jpeg 。非工作的(我正在尝试解决这个问题)并不是因为Content-Type不同。

我想知道是否有人可以告诉我是否可以让flash基本上解析URI,就好像它是image/jpeg一样,无论内容类型如何?

  

我无权访问该来源   目前的代码,但我只是   抛出这个以获得输入

     

如果需要,我明天会尝试获取一些源代码

编辑:好的,我现在可以访问该来源了。这是加载图像的部分:

postcardImage = new Image();
postcardImage.loadImage(imagePath);

我认为Image构造函数是flash / AS的原生代码,但我无法使用loadImage方法谷歌,所以它必须是自定义的,对吗?

或者Image构造函数本身可以自定义吗?具有Image方法的原始loadImage的扩展版本等?

无论如何,有谁知道如何查看loadImage的源代码?

编辑#2 :我做了ack-grep并找到了库中定义的loadImage方法的源代码:

public class Image extends Sprite {

    private var _source:String;
    private var _loader:Loader;
    private var _bmapData:BitmapData;
    private var _loadedBytes:Number;
    private var _totalBytes:Number;

    public function Image() {
        trace('IMAGE');
    }

    public function loadImage(s:String):void {
        _source = s;
        _loader = new Loader();
        _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
        _loader.contentLoaderInfo.addEventListener(Event.INIT, onLoading);
        _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
        _loader.load(new URLRequest(_source));

        function onProgress(e:ProgressEvent):void {
            _loadedBytes = e.target.bytesLoaded;
            dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS));
            if(!_totalBytes) {
                setTotalBytes(e.target.bytesTotal);
            }
        }

        function onLoading(e:Event):void {
            _loader.contentLoaderInfo.removeEventListener(Event.INIT, onLoading);
        }

        function onLoaded(e:Event):void {
            _bmapData = e.target.content.bitmapData;
            addChild(e.target.content);
            dispatchEvent(new Event(Event.COMPLETE));
            _loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoaded);
        }
    }

    public function getBmapData():BitmapData {
        return _bmapData;
    }

    public function duplicate():Image {
        var dup:Image = new Image();
        dup.addChild(new Bitmap(_bmapData.clone()));
        return dup;
    }

    public function getLoadedBytes():Number {
        return _loadedBytes;
    }

    private function setTotalBytes(n:Number):void {
        _totalBytes = n;
        dispatchEvent(new Event("TOTALBYTES_SET"));
    }

    public function getTotalBytes():Number {
        return _totalBytes;
    }

}   

有人可以提供关于如何对此进行loadBytes的建议吗?我正在考虑定义一个自定义方法,loadResource或者可以加载而不管Content-Type ...或只是在当前load方法和内部创建一个可选参数,根据什么分支过了。

2 个答案:

答案 0 :(得分:2)

简短回答:是的。

我认为代码在幕后使用Loader对象来进行实际的图像加载/检索(这是做这些事情的标准方法)。 Loader对象支持PNG,JPEG和GIF(仅限第一帧)格式。

现在,我不确定Loaders是否使用响应的内容类型来猜测图像格式(我猜不会,但我可能错了)。我知道Loaders有一个loadBytes()方法直接从其原始字节加载图像 - 在这种情况下,仅嗅的格式使用图像的实际数据,因为没有HTTP请求直接参与。因此,如果真的是内容类型是罪魁祸首,您可以将图像作为原始数据单独加载,然后使用loadBytes()从原始数据中获取图像对象,完全绕过该问题。

当然,我们必须看到代码才能真正了解正在发生的事情。

答案 1 :(得分:2)

我最近一直在玩ByteArray方法,听起来很有趣。我已经使用一种传递八位字节流的URL的方法修改了Image类。让我知道它是如何工作的!

注意:我没有设置_loadedBytes和_totalBytes属性,但我正在绘制加载的图像以启用公共'getBmapData'方法。

package {
import flash.utils.ByteArray;
import flash.net.URLStream;
import flash.display.Bitmap;
import flash.net.URLRequest;
import flash.events.ProgressEvent;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;

public class Image extends Sprite {

    private var _source : String;
    private var _loader : Loader;
    private var _bmapData : BitmapData;
    private var _loadedBytes : Number;
    private var _totalBytes : Number;
    private var _stream : URLStream;
    private var _bytes:ByteArray;

    public function Image() {
        trace('IMAGE');
    }

    public function loadImage(s : String) : void {
        _source = s;
        _loader = new Loader();
        _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
        _loader.contentLoaderInfo.addEventListener(Event.INIT, onLoading);
        _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
        _loader.load(new URLRequest(_source));

        function onProgress(e : ProgressEvent) : void {
            _loadedBytes = e.target.bytesLoaded;
            dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS));
            if(!_totalBytes) {
                setTotalBytes(e.target.bytesTotal);
            }
        }

        function onLoading(e : Event) : void {
            _loader.contentLoaderInfo.removeEventListener(Event.INIT, onLoading);
        }

        function onLoaded(e : Event) : void {
            _bmapData = e.target.content.bitmapData;
            addChild(e.target.content);
            dispatchEvent(new Event(Event.COMPLETE));
            _loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoaded);
        }
    }



    // ByteArray methods
    // adapted from Ted Patrick's 
    // http://ted.onflash.org/2007/12/progressive-image-loading-with.php

    public function loadBytes( s:String = "" ):void {

        // FOR EASY TESTING ONLY:
        if( s == "" ) s = "http://onflex.org/flexapps/applications/ProgressiveImageLoading/jpg.jpg";        

        // create URLStream with listeners
        _stream = new URLStream();
        _stream.addEventListener( ProgressEvent.PROGRESS , streamProgress );

        // Not firing, so lets not use it...
        //_stream.addEventListener( Event.COMPLETE , streamComplete );


        // create Loader for later
        _loader = new Loader();

        // create new ByteArray instance
        _bytes = new ByteArray();

        // go ahead and add it to the display list
        addChild( _loader );

        // start the show!
        _stream.load( new URLRequest(s) );

    }

    private function streamProgress(p : ProgressEvent) : void {

        trace("PROGRESS: ",  p.bytesLoaded, "of", p.bytesTotal );

        if( _stream.connected ) _stream.readBytes(_bytes, _bytes.length );

        if( _bytes.length == p.bytesTotal ) {

            // get rid of the event listeners to avoid re-firing 
            _stream.removeEventListener( ProgressEvent.PROGRESS , streamProgress ); 

            streamComplete();   
        }
    }

    private function streamComplete() : void {
        _loader.loadBytes( _bytes );
        _loader.contentLoaderInfo.addEventListener( Event.INIT, makeBitmapData );
    }

    private function makeBitmapData( e:Event ):void{

        _loader.contentLoaderInfo.removeEventListener( Event.INIT, makeBitmapData );

        // set the bitmapData for the other public methods
        _bmapData = new BitmapData(_loader.width, _loader.height );
        _bmapData.draw( this );
    }

    //-----




    public function getBmapData() : BitmapData {
        return _bmapData;
    }

    public function duplicate() : Image {
        var dup : Image = new Image();
        dup.addChild(new Bitmap(_bmapData.clone()));
        return dup;
    }

    public function getLoadedBytes() : Number {
        return _loadedBytes;
    }

    private function setTotalBytes(n : Number) : void {
        _totalBytes = n;
        dispatchEvent(new Event("TOTALBYTES_SET"));
    }

    public function getTotalBytes() : Number {
        return _totalBytes;
    }
}  
}