I have had a problem loading images into Adobe Flash via Actionscript3.0 if they are in a directory structure that has an underscore character (‘_’) in it. Since the underscore character is not part of the E4X standard for URLs, you cannot directly use flash.display.Loader to load an image which may have an underscore in it. For example, if you have a file:

C://images/_someDir/someImage.png

Loader will fail by not finding the URL. Digging deeper, if you show the Loader’s URL, you will see that it escaped the underscore character with the ASCII hex reference of %5F.

I have not found a way to successfully “unescape” this URL line and have the Loader class read it correctly. Further, I cannot simply change the directory structure, since it is an integrated work environment, and many other programs expect the current naming.

So here is the workaround for me: I place the SWF in the same directory as the images (or the images are in a sub-dir, with no underscores), and load the image with URLLoader, then load that byte stream as an image. I am not quite sure why Loader and URLLoader handle URLs differently. What I suspect that URLLoader treats the reference as a relative link, so doesn’t pick up the directory with an underscore. (Or, maybe, it just handles URLs correctly, despite the standard. Underscores are part of operating systems, after all.)

Here is a sample set of code to do this:

[...]

import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
//import flash.text.TextField;

/**
 * Load image as byte stream.
 * @param   imgNm
 */
protected function loadImage(imgNm:String):void
{
    //trace("loadImage: imgNm = " + imgNm);
    
    var fileRequest:URLRequest = new URLRequest(encodeURIComponent(imgNm));
    
    //trace("\t fileRequest.url = " + fileRequest.url);
    
    try 
    {
        var imgLdr:URLLoader = new URLLoader();
        imgLdr.dataFormat = URLLoaderDataFormat.BINARY;
        imgLdr.addEventListener(ProgressEvent.PROGRESS, progHnd, false, 0, true);
        imgLdr.addEventListener(Event.COMPLETE, onURLLoaderComplete, false, 0, true);
        imgLdr.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
        imgLdr.load(fileRequest);
    }
    catch (ero:Error)
    {
        trace("Error: loadImage: " + ero + "\n" + ero.getStackTrace() );
    }
    finally { }
}

/**
 * Show loading progress.
 * @param   e
 */
protected function progHnd(e:ProgressEvent):void 
{
    //statusTextField.text = e.bytesLoaded + " of " + e.bytesTotal;
}

/**
 * Handles errors for both URLLoader and Loader.  The try-catch prevent errors from a non-existent ProgressEvent class from showing up.
 * @param   e
 */
protected function ioErrorHandler(e:IOErrorEvent):void 
{
    //trace("ioErrorHandler");
    
    try{e.target.removeEventListener(ProgressEvent.PROGRESS, progHnd); }catch (ero:Error){}
    e.target.removeEventListener(Event.COMPLETE, onLoaderComplete);
    e.target.removeEventListener(Event.COMPLETE, onURLLoaderComplete);
    e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
    
    trace("Image load error: " + e.target + "\n" + e.text);
}

/**
 * Convert URLLoader data into Loader data.
 * @param   e
 */
protected function onURLLoaderComplete(e:Event):void 
{
    //trace("onURLLoaderComplete");
    try{e.target.removeEventListener(ProgressEvent.PROGRESS, progHnd); }catch (ero:Error){}
    e.target.removeEventListener(Event.COMPLETE, onLoaderComplete);
    e.target.removeEventListener(Event.COMPLETE, onURLLoaderComplete);
    e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
    
    //trace("\t URLLoader(e.target) = " + e.target);
    
    // Convert URLLoader into Loader data.  Workaround for URLs with underscores.
    var newLdr:Loader = new Loader();
    newLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete, false, 0, true);
    newLdr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
    newLdr.loadBytes(URLLoader(e.target).data);
    
    statusTF.text = "";
}

/**
 * Convert to Bitmap.
 * @param   e
 */
protected function onLoaderComplete(e:Event):void 
{
    //trace("onLoaderComplete");
    
    try{e.target.removeEventListener(ProgressEvent.PROGRESS, progHnd); }catch (ero:Error){}
    e.target.removeEventListener(Event.COMPLETE, onLoaderComplete);
    e.target.removeEventListener(Event.COMPLETE, onURLLoaderComplete);
    e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
    
    var bm:Bitmap = Bitmap(LoaderInfo(e.target).content);
    
    //trace("\t LoaderInfo(e.target) = " + LoaderInfo(e.target).url);
    //trace("\t bm = " + bm);
}

[...]

– 30 –

Advertisements