Может ли Flash / AS3 загружать внешние изображения независимо от типа содержимого? - PullRequest
3 голосов
/ 21 июня 2011

Отказ от ответственности: я не флеш-разработчик но я пытаюсь решить проблему со вспышкой. Пожалуйста, не думайте, что я глубоко знакомы с AS или Flash, потому что я нет.

Дилемма, с которой я сталкиваюсь в настоящее время, заключается в том, что я размещаю ресурс application/octet-stream. В моем коде Actionscript я использую некоторую библиотеку, которая (из того, что я могу вспомнить) делает new Image и загружает ресурс в тот объект, который был создан.

Существует метод, loadImage(url), который принимает URL-адрес, и именно здесь вы указываете ему путь к изображению.

У меня нет доступа к исходному коду loadImage, поэтому я точно не знаю, что он делает, но рабочий загружает изображение нормально, потому что Content-Type равен image/jpeg. Нерабочий (этот я пытаюсь исправить) не из-за различных Content-Type.

Мне интересно, может ли кто-нибудь сказать мне, могу ли я заставить флэш-память в основном анализировать URI, как если бы это было image/jpeg, независимо от типа содержимого?

У меня нет доступа к источнику код на данный момент, но я просто выбрасывая это, чтобы получить ввод

Если понадобится, завтра попробую получить исходный код

РЕДАКТИРОВАТЬ: Хорошо, теперь у меня есть доступ к источнику. Вот часть, которая загружает изображение:

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

Я предполагаю, что Image конструктор является родным для flash / AS, но я не смог Google loadImage метод, поэтому он должен быть пользовательским, верно?

Или сам конструктор Image может быть пользовательским? Расширенная версия оригинального Image с loadImage методом и тому подобное?

В любом случае, кто-нибудь знает, как я могу просмотреть исходный код loadImage?

EDIT # 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 и внутри, разветвляться на основе того, что было передано. 1055 *

Ответы [ 2 ]

2 голосов
/ 21 июня 2011

В последнее время я играю с методами ByteArray, и это звучит забавно. Я исправил ваш класс Image с помощью метода для передачи URL-адреса потока октетов. Дайте мне знать, как это работает!

примечание: я не устанавливаю свойства _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;
    }
}  
} 
2 голосов
/ 21 июня 2011

Краткий ответ: Да.

Я бы предположил, что код использует объект Loader за кулисами для фактической загрузки / извлечения изображения (это стандартный способ сделать такие вещи). Объекты загрузчика поддерживают форматы PNG, JPEG и GIF (только первый кадр).

Теперь я не уверен, что загрузчики используют тип содержимого ответа, чтобы угадать формат изображения (я бы предположил, что нет, но я могу ошибаться). Я знаю, что в Loaders есть метод loadBytes(), который загружает изображение непосредственно из его необработанных байтов - формат сниффинг only использует в этом случае фактические данные изображения, поскольку HTTP-запрос напрямую не задействован. Таким образом, если виновником является действительно тип контента, вы можете загрузить изображение отдельно как необработанные данные, а затем получить объект изображения из этих необработанных данных, используя loadBytes(), полностью обойдя проблему.

Мы должны были бы увидеть код, чтобы действительно знать, что происходит, конечно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...