Tutorial: ActionScript loading External JPG file

As part of a larger application in which our Flash ActionScript application will read in image files specified in an XML file, we need to be able to load and display a single jpg file. The two files described in these notes do the job. A Flash document named getsnapshot.fla and an ActionScript file: Snapshot.as. The basic files are described and then an enhanced version that provides the functionality of catching an error.

Basic Snapshot class definition with tester getsnapshot

The job of loading the jpg file is done using a class definition:

package familyscenes {

import statements

public class Snapshot extends MovieClip{

}

other method

}

}

We want a Snapshot object to inherit properties of MovieClips such as x, width, scaleX, etc, so this is why we use the coding ….extends MovieClip.

The Snapshot constructor (the method invoked to create a Snapshot object) takes 3 parameters:

public function Snapshot(picname:String,hook:MovieClip,fixedw:int):void {

The first is the name of the image file. The second is a MovieClip instance in the .fla file. This will be used with addChild to make the image file visible. It is important to remember that objects created by ActionScript need to be added explicitly to the so-called Display list to be visible on the Stage. The last parameter is used to re-size the image. The re-sizing is done by setting the width to fixedw and then setting the scaleY to the new scaleX. This accomplishes re-sizing without changing the aspect ratio. Recall this is done automatically in HTML, but not in ActionScript. (Note: the enhanced version doesn't always do the re-sizing. See below.)

The loading of an external file is not accomplished immediately. Instead, a call is made to the appropriate addEventListener to invoke another method (imageloaded) when the loading is complete.

Here is the code for the file Snapshot.as. NOTE: I place this is a folder named familyscenes in a folder named as3. In a PC, the as3 folder is at the top of the same drive as the getsnapshot.fla file. In a MAC, the as3 folder and the getsnapshot.fla folder are in the same folder.

package familyscenes{ / header for package
import flash.display.*; / needed for addChild
import flash.net.URLRequest; / needed for URLRequest
import flash.events.*; / needed for COMPLETE
public class Snapshot extends MovieClip { / header for class
internal var ldr:Loader;
internal var ldrcontent:DisplayObject;
internal var fw:int;
public function Snapshot(picname:String,hook:MovieClip,fixedw:int):void { / constructor method
var imageURLRequest:URLRequest = new URLRequest(picname); / sets up call to load image file
ldr = new Loader(); / does the loading
ldr.load(imageURLRequest); / start the load
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,imageloaded); / sets up call when loading is complete
hook.addChild(this); / this created object will be displayed
fw = fixedw; / save the value of the fixedw parameter
} / end method
internal function imageloaded(e:Event):void { / invoked when loading complete
ldrcontent = ldr.content; / Get content 'out of' loader object
this.addChild(ldrcontent); / add to display list
ldrcontent.width = fw; / Set width
ldrcontent.scaleY = ldrcontent.scaleX; / Make Y scale the same as just changed X scale
} / Close method
} / Close class
} / Close package

This code is tested using the getsnapshot.fla file. It contains one movieclip symbol that needn't contain any material. Move an instance of the symbol to the Stage. Make its instance name hook.

It contains 2 lines (Open Window/Actions and put in the first and only frame:

import familyscenes.*;

var firstscene:Snapshot = new Snapshot("picnic3.jpg",hook,300);

In File/Publish Settings, click on Flash and then Settings and then browse to the c:\as3 folder. This 'tells' Flash where to find the familyscenes package. Note: the familyscenes package contains only one class, so the import statement could be:

import familyscenes.Snapshot;

To test this program, you need to make sure the file names in the call to Snapshot, in my case "picname3.jpg", is located in the same folder as the .fla file (which will be the folder holding the .swf file).

Enhanced Snapshoterror file with testing getsnapshoterror

You may say that errors need to be caught during development time and so production code does not need to do any error handling. For instructional purposes and also because it has validity, I claim that I need to make sure that the Snapshot code does not have a runtime error if the image file is not found. Instead, my strategy is to return a specific, let's call it a dummy image file. The end-users still will know that something went wrong but the application won't stop with a Flash error.

The way this is accomplished is to invoke addEventListener for a different event: IOErrorEvent.IO_ERROR. The function that 'catches' this event reads in the fixed file.

I made another addition to this file for error handling, but I haven't actually arranged for a test. I put some of the code in a try {} catch { } structure. What this does is suppress any errors that arise immediately in the code in the try section. If there is an error, the catch clause is taken. The situation of NOT finding a file is not such an error. Another name of such errors is synchronous errors. The IO_ERROR is an asynchronous error. If it occurs, it does so later. NOTE: see a later tutorial for a situation in which I did arrange for a synchronous error.

This version of the program, I call it Snapshoterror, has another difference from the original. I decided that making an image with width less than the amount specified by the parameter might stretch a file too much, so I put an a conditional statement.

The code for Snapshoterror.as is follows. The file is placed in the familyscenes folder in the as3 folder as described previously.

package familyscenes{

import flash.display.*;

import flash.net.*;

import flash.events.*;

import flash.errors.*;

public class Snapshoterror extends MovieClip {

internal var ldr:Loader;

internal var ldrcontent:DisplayObject;

internal var fw:int;

public function Snapshoterror(picname:String,hook:MovieClip,fixedw:int):void {

//trace("in Snapshoterror, picname is "+picname);

ldr = new Loader();

ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);

ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,imageloaded);

try {

var imageURLRequest:URLRequest = new URLRequest(picname);

ldr.load(imageURLRequest);

} catch (ev:Error) {//for synchronous (immediate) errors

trace("in catch, ev is "+ev);

}

hook.addChild(this);

fw = fixedw;

}

internal function imageloaded(e:Event):void {

ldrcontent = ldr.content;

this.addChild(ldrcontent);

if (ldrcontent.width>fw) {

ldrcontent.width = fw;

}

ldrcontent.scaleY = ldrcontent.scaleX;

}

internal function errorHandler(ev:IOErrorEvent):void {

//trace("in errorHandler, ev is "+ev);

var imageURLRequest:URLRequest = new URLRequest("missingimage.jpg");

ldr.load(imageURLRequest);

}

}

}

To test this program, I need to write code in the fla file that will trigger the IO_ERROR. I wrote a new file names getsnapshoterror. In the one and only frame, Window/Actions panel, write the following (assuming you have a file named picnic3.jpg in the same folder and you DO NOT have a file named blah.jpg.

import familyscenes.*;

var firstscene:Snapshoterror = new Snapshoterror("picnic3.jpg",hook,300);

var secondscene:Snapshoterror = new Snapshoterror("blah.jpg",hook,100);

The following appeared when I want this program:

Notice that the Missing Image picture is pretty small in comparison with the other one.

The Snapshoterror.js file is the one I use for the applications involving reading in an XML file with the names of image files.