views:

240

answers:

3

I have an image that I am attempting to load, and then reload. Here is my code for the loading of the image:

    public function loadImage(url:String, _w:int, _h:int):void 
    {   
        this._stwidth = _w;
        this._stheight = _h;
        this._imageURL = url;

        if(!_imageURL)
        {
            return;
        }

        this.alpha = 1.0;   //need this because we might have just faded the image out

        _ldr.alpha = 0.0;
        _prog.alpha = 1.0;
        _sqr.alpha = 0.0;
        _sqr.graphics.clear();

        if(_hasLoaded) 
        {
            try
            {
                _ldr.close();
                _ldr.unload();                  
            }
            catch(e:Error)
            {
                //trace("bmdisplay has loaded once, but there was an error: " + e.message);
            }           
        }

        _ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
        _ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
        _ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
        _ldr.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
        _ldr.contentLoaderInfo.addEventListener(Event.INIT, onOpen);
        _ldr.load(new URLRequest(_imageURL));
    }

For some reason, this code will not load the image without issuing an Error upon the 2nd load. Can someone please help me figure this out?

I am totally lost on why my variable _asLoaded would do me wrong. I have an onComplete() handler, which sets that var to true, and I never set it to false after that.

I don't know what else I should be trying...

Thanks

+2  A: 

Sometimes back I wrote a helper class to achieve something similar. The helper class extends Loader and provides automatic scaling of image. Here is the code for that class:

package {
import flash.display.Loader; import flash.geom.Rectangle; import flash.net.URLRequest; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; public class ImageLoader extends Loader { private var _imageURL:String; // URL of image private var _imageBoundary:Rectangle; // boundary rectangle for the image private var _loaded:Boolean; // flag which tells whether image is loaded or not. private var _isLoading:Boolean; // flag which say if any loading is in progress //Constructor function, which calls Loader's constructor // and loads and resize the image public function ImageLoader(url:String = null, rect:Rectangle = null):void { super(); _imageURL = url; _imageBoundary = rect; _loaded = false; _isLoading = false; loadImage(); } // sets the image for the loader and loads it public function set imageURL(url:String):void { _imageURL = url; loadImage(); } // sets the boundary of the image and resizes it public function set boundary(rect:Rectangle):void { _imageBoundary = rect; resizeImage(); } private function removeListeners():void { this.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete); this.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onError); this.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onError); } private function onComplete(e:Event):void { _loaded = true; _isLoading = false; removeListeners(); resizeImage(); } //In case of error, we are not propogating the event private function onError(e:Event):void { e.stopImmediatePropagation(); removeListeners(); } // real loading goes here // it first closes and unloads the loader and // then loads the image private function loadImage():void { if (_isLoading) { trace("Some loading is in progess"); return; } try { this.close(); this.unload(); } catch(e:Error) { //discarded } if (!_imageURL) return; _loaded = false; _isLoading = true; this.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); this.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError); this.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError); this.load(new URLRequest(_imageURL)); } // standard resizing function for image so that it's // aspect ratio is maintained. private function resizeImage():void { if (!_imageBoundary || !_loaded) return; var aspect:Number = width / height; var cAspect:Number = _imageBoundary.width / _imageBoundary.height; if (aspect <= cAspect) { this.height = _imageBoundary.height; this.width = aspect * this.height; } else { this.width = _imageBoundary.width; this.height = this.width / aspect; } this.x = (_imageBoundary.width-this.width)/2 + _imageBoundary.x; this.y = (_imageBoundary.height-this.height)/2 + _imageBoundary.y; } } }
And you can use it like this:
var _imageLoader:ImageLoader = new ImageLoader();
_imageLoader.imageURL = "http://some-image-url";
_imageLoader.boundary = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); // or whatever suits you
ImageLoader extends Loader class so you can listen to all the Events dispatches by Loader class. Hope it helps.

bhups
nice. i appreciate the help.
jml
@bhups : i created a new thread here:http://stackoverflow.com/questions/1997655/how-to-get-a-stage-calculation-to-resize-an-image-w-r-t-c can you help me with what i might be missing? thanks so much for your help w/ this.
jml
Hi again bhups, I have a problem sometimes when an error is detected inside of the loadImage() function. Can you tell me what the problem is? I am finding (if I trace) that the first time the image is loaded an error is caught. If I discard the error, it loads, but then if I return, the image never loads. So for me, it makes little sense to be reloading this way. There should be a more clear definition, like a check on _loaded... but this doesn't work either? :s
jml
every time i try to load an image the 2nd time, i error out. currently this is leading to the site not loading an image after it has loaded once. this is such a freekin headache. the error is "TypeError: Error #1009: Cannot access a property or method of a null object reference." and then i get "Error #2029: This URLStream object does not have a stream opened."... i don't understand why though, because i DO have an image loaded when this happens.!!!@#!?
jml
FWIW, i know that in this instant, the URL i feed to the loader _is_ in fact valid.
jml
I should mention that I edited my post before the last two comments, in order to make my problem more clear.
jml
@jml: I think the issue is happening due to loading an Image, while other one is in progress. So i have added an _isLoading flag which helps ImageLoader in identifying such scenarios. I have edited the answer for the same.
bhups
nope; sorry. it is _not_ loading at that point. in every case (and i have tried this under a ton of different scenarios), the image is already loaded. the reason that i know it has loaded is because the onComplete handler is activated at that point...
jml
+1  A: 

Try instantiating new Loader, probably trying to recycle it is giving you the problem

PeanutPower
is this common practice? would it incur latency?
jml
i tried instantiated a new one and that doesn't seem to work as well.
jml
+1  A: 

i would declare _ldr inside the function so its dead every time you start this function. and i also would not use this unload() and close() methods. its much simpler if make some thing like this (you need to have a empty movieclip called "ldrHelper"):

public function loadImage(url:String, _w:int, _h:int):void 
{
    // do your job and die bravely, no need to be global 
    var _ldr:Loader = new Loader();
    this._stwidth = _w;
    this._stheight = _h;
    this._imageURL = url;

    if(!_imageURL)
    {
        return;
    }

    this.alpha = 1.0;   //need this because we might have just faded the image out

    // now you will need to make alpha = 1 on ldrHolder since _ldr is dead after this function
    ldrHolder.alpha = 0.0;
    _prog.alpha = 1.0;
    _sqr.alpha = 0.0;
    _sqr.graphics.clear();


   // remove the old image, doesn't matter whether its empty or not
   while(ldrHolder.numChildren > 0){
         ldrHolder.removeChildAt(0);
   }

    //add image
    ldrHolder.addChild(_ldr);

    _ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
    _ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
    _ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
    _ldr.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
    _ldr.contentLoaderInfo.addEventListener(Event.INIT, onOpen);
    _ldr.load(new URLRequest(_imageURL));
}
antpaw
i had already sorta figured this out at this point, although i do like your solution of using removeChild() and addChild() to sort of wrap it up. Ultimately my answer, which is currently operative (and which doesn't yield any errors) is to simply reload a new image, _not_ recycle the loader, to _not_ try/catch, and i dispatch an event upon complete for other classes above this class in the display list chain.
jml