3 votes

Flash/AS3 peut-il charger des images externes sans tenir compte du type de contenu ?

Disclaimer : Je ne suis pas un développeur Flash mais j'essaie de résoudre un problème de flash. S'il vous plaît ne supposez pas que je suis intimement familier avec AS ou Flash, car je ne le suis pas. pas.

Le dilemme que j'ai actuellement est que j'héberge une ressource qui est application/octet-stream . Dans mon code Actionscript, j'utilise une bibliothèque qui (d'après ce dont je me souviens) fait ce qui suit new Image et charge une ressource dans cet objet qui a été créé.

Il y a une méthode, loadImage(url) qui accepte un url et c'est là que vous lui fournissez le chemin vers l'image.

Je n'ai pas accès à la loadImage code source, donc je ne sais pas exactement ce qu'il fait, mais celui qui fonctionne charge l'image correctement parce que l'option Content-Type est image/jpeg . Celui qui ne fonctionne pas (celui que j'essaie de réparer) ne fonctionne pas à cause de la différence entre les deux. Content-Type .

Je me demande si quelqu'un peut me dire si je peux faire en sorte que le flash analyse l'URI comme s'il s'agissait de image/jpeg indépendamment du Content-Type ?

Je n'ai pas accès à la source code source pour le moment, mais je suis juste jeter cela là-bas pour obtenir des commentaires

Si nécessaire, j'essaierai d'obtenir le code source demain.

EDITAR: Ok, j'ai accès à la source maintenant. Voici la partie qui charge l'image :

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

Je suppose que Image le constructeur est natif de flash/AS, mais je n'ai pas été capable de googler le loadImage donc il doit être personnalisé, non ?

Ou le constructeur d'image lui-même pourrait-il être personnalisé ? Une version étendue de l'original Image con loadImage et autres ?

En tout cas, quelqu'un sait-il comment je peux voir le code source de loadImage ?

EDIT #2 : J'ai fait un ack-grep et a trouvé le code source de la loadImage définie dans une bibliothèque :

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;
    }

}   

Quelqu'un peut-il me conseiller sur la façon dont je peux faire le loadBytes sur ce sujet ? Je pensais définir une méthode personnalisée, loadResource ou quelque chose qui peut se charger indépendamment du Content-Type... ou simplement créer un paramètre optionnel dans l'interface courante de l'utilisateur. load et à l'intérieur, se ramifier en fonction de ce qui a été passé.

2voto

Cameron Points 32208

Réponse courte : Oui.

Je suppose que le code utilise un Loader en arrière-plan pour effectuer le chargement/la récupération de l'image (c'est la façon standard de faire ce genre de choses). Les objets chargeurs prennent en charge les formats PNG, JPEG et GIF (première image uniquement).

Je ne sais pas si les chargeurs utilisent le type de contenu de la réponse pour deviner le format de l'image (je ne pense pas, mais je peux me tromper). Je sais que les chargeurs ont un loadBytes() qui charge une image directement à partir de ses octets bruts -- le reniflage de format sólo utilise les données réelles de l'image dans ce cas, car il n'y a pas de requête HTTP directement impliquée. Donc, si c'est vraiment le type de contenu qui est en cause, vous pouvez charger l'image séparément en tant que données brutes, puis obtenir un objet image à partir de ces données brutes à l'aide de la commande loadBytes() ce qui permet de contourner entièrement le problème.

Il faudrait voir le code pour savoir vraiment ce qui se passe, bien sûr.

2voto

NHubben Points 246

J'ai joué avec les méthodes ByteArray ces derniers temps et cela semblait amusant. J'ai modifié votre classe Image avec une méthode pour passer l'URL du flux d'octets. Faites-moi savoir comment ça se passe !

note : Je ne définis pas les propriétés _loadedBytes et _totalBytes, mais je dessine l'image chargée pour activer la méthode publique '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;
    }
}  
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X