Skip to content


Preloading Multiple Images with Actionscript

Please view my updated code

One of my new projects involves a lot of imagery so I decided to write a class that I could send it an array of images and preload them with a loading bar. The code below doesn’t have a loading bar, but if you trace out the code you can see how you can integrate a loading animation to the code. Here is what I have that works for what I need, although I would like to go through it to see if I can make it more efficient.

Here is the Main Document Class:

package {
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.text.TextFormat;
	import flash.text.TextField;
	import fl.controls.TextArea;
	import fl.controls.ScrollPolicy;

	public class Main extends Sprite
	{
		// array of all images to be prelaoded before the movie begins:
		private var imgArray:Array;

		// the class to handle all the images
		private var imgPreload:MultipleImagePreload;

		//text area component
		private var output:TextArea;  

		public function Main()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;

			showOutput();

			init();
		}

		private function init():void
		{

			imgArray = new Array();
			imgArray[0] = "http://manewc.com/projects/flash/i/infused-blackraspberry.png";
			imgArray[1] = "http://manewc.com/projects/flash/i/infused-blueberry.png";
			imgArray[2] = "http://manewc.com/projects/flash/i/infused-coconut.png";
			imgArray[3] = "http://manewc.com/projects/flash/i/infused-lemonlime.png";
			imgArray[4] = "http://manewc.com/projects/flash/i/infused-peach.png";
			imgArray[5] = "http://manewc.com/projects/flash/i/infused-pineappleorange.png";
			imgArray[6] = "http://manewc.com/projects/flash/i/infused-strawberry.png";

			imgPreload = new MultipleImagePreload(imgArray);
			addChild ( imgPreload );

			stage.addEventListener ( Event.ENTER_FRAME, checkPreload );

		}

		private function checkPreload(e:Event):void
		{
			if ( imgPreload.chkLoaded )
			{
				Message ( "\n====================\nALL IMAGES LOADED\n====================\n" );

				stage.removeEventListener ( Event.ENTER_FRAME, checkPreload );
			}
		}

		private function showOutput():void
        {
			output = new TextArea();
			output.verticalScrollPolicy = ScrollPolicy.ON;
			output.condenseWhite = true;
			output.setSize(stage.stageWidth, stage.stageHeight);
			output.move(0, 0);
			addChild(output);
        }

		public function Message(msg:String):void
		{
			output.appendText ( msg );
		}

	}
}

The class that is the Preloader

package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.setInterval;
	import flash.utils.clearInterval;

	public class MultipleImagePreload extends Sprite
	{
		public var images:Array;
		public var chkLoaded:Boolean = false;

		private var imgArray:Array;

		// array of images.. onload event
		private var imgLoadArray:Array;

		// array of LoadImage class
		private var loadArray:Array;

		// variables for our timer events
		private var initLoadTimer:uint;
		private var preLoadTimer:uint;

		// variables for the preload process
		private var getTotalBits:Number; // the tally for the total bits
		private var imageTotalSize:Number;
		private var imagePreLoadSize:Number; // the tally for preloading

		public function MultipleImagePreload(images:Array)
		{
			imgArray = images;

			// Load in the images.
			loadArray = new Array();

			for ( var i:uint; i < images.length; i++ )
			{
				// load the image
				loadArray[i] = new LoadImage( imgArray[i] );

				// display the image to stage
				addChild ( loadArray[i] );

				// send them off the stage
				loadArray[i].x = -9999;
			}

			initLoadTimer = setInterval(onLoadImage, 500);
		}

		private function onLoadImage():void
		{
			var imgLoadArray = new Array();

			for ( var i:uint=0; i < imgArray.length; i++ )
			{
				getTotalBits = loadArray[i].getBits();

				if ( getTotalBits > 0 )
				{
					// check again.
					imgLoadArray[i] = loadArray[i];
				}
			}

			if ( imgLoadArray.length == imgArray.length )
			{

				clearInterval ( initLoadTimer );

				imageTotalSize = 0;

				// add up the size of all images
				for ( var u:uint=0; u < imgArray.length; u++ )
				{
					if ( loadArray[u].getBits() ) /* Safari is requiring this */
					{
						imageTotalSize += loadArray[u].getBits();

					}
				}

				Main(root).Message( "Total Size (bits): " + imageTotalSize + "\n" );

				// we now have recorded all file sizes.. now start the preloading
				preLoadTimer = setInterval(preLoadImage, 50);
			}
		}

		private var loadStat:Number;

		private function preLoadImage():void
		{
			imagePreLoadSize = 0;

			// add up the size of all images
			for ( var p:uint=0; p < imgArray.length; p++ )
			{
				imagePreLoadSize += loadArray[p].getBitsLoaded();
			}

			if ( ( imagePreLoadSize / imageTotalSize ) )
			{
				loadStat = Math.floor(100 * (imagePreLoadSize / imageTotalSize));

				if ( loadStat >= 100 )
				{
					// clear the timer
					clearInterval ( preLoadTimer );

					// set the boolean variable to true to notify all images are loaded
					chkLoaded = true;

					Main(root).Message ("100% Loaded\n");
				}
				else
				{
					Main(root).Message (Math.floor(100 * (imagePreLoadSize / imageTotalSize)) + "% Loaded\n");
				}
			}
		}
	}
}

The class that will load in the image

package {
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.net.URLRequest;

    public class LoadImage extends Sprite {

		private var url:String;
		private var imageHolder:Sprite;
		public var bits:Number;
		public var bitsLoaded:Number;
		public var totalBits:Number;

        public function LoadImage(url:String) {
			var loader:Loader = new Loader();
            configureListeners(loader.contentLoaderInfo);

            var request:URLRequest = new URLRequest( url );
            loader.load(request);

			imageHolder = new Sprite();
			addChild ( imageHolder );
            imageHolder.addChild(loader);
        }

        private function configureListeners(dispatcher:IEventDispatcher):void {
			dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			dispatcher.addEventListener(Event.COMPLETE, completeHandler);
        }

        private function completeHandler(event:Event):void {
			Main(root).Message( "Image Load Event Complete\n" )
		}

		public function getBits()
		{
			return ( bits );
		}

		public function getBitsLoaded()
		{
			return ( bitsLoaded );
		}

        private function progressHandler(event:ProgressEvent):void {
			bitsLoaded = event.bytesLoaded;
			bits = event.bytesTotal;
        }

    }
}

Posted in Image Effects, Preloading, manewc.com.


9 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Lubakis says

    This was very usefull to me! Thank you for writing that code.

  2. Erik says

    Excellent code. Thanks for sharing! Very useful, very complete.

  3. awais says

    hey its an excellent code,
    can I see it working somewhere

  4. admin says

    Hey All,

    Please view the updated code:

    http://manewc.com/2008/09/02/preloading-multiple-image-demo/

    Sorry for any confusion!

    Morgan

  5. Bruno Mikoski says

    Very good!

    Good job!

  6. namb5 says

    Thank very much !

  7. Brandon R says

    I have an application that loads a bunch of thumbnails in the initial .swf file. Then when they click on the thumbnail, it displays the large version of that photo that it got from a url source. Now if I embed all the large images in my .swf, initial load could take forever for slow bandwidth users. So I want the images to load after website first loads. But the problem is, when they click, it sometimes takes 4-6 seconds for each photo to appear. How can I have the large images load in the background after initial page load? Will your image/array technique work for that?

    If it does…
    Lets say the user load the website, 10 seconds later the user clicks the first image to enlarge. By this time the array has been filled up with only the first two images (out of 10 total images). Will the user be able to quickly view that first image? Or will the user have to wait till the whole array is filled before they can view the first image in the array?

    THANKS A TON FOR THE HELP!

    If you want to see the specific example I am talking about, go to this address, then “photos”: http://www.fischerreinkewedding.com

  8. admin says

    Hi Brandon, I don’t feel like you are going to want to load all the large images after everything else. Ideally you will want to load the large image when the thumbnail image is clicked on. You should take a look at my image gallery project:

    http://manewc.com/category/image-gallery-project/

    more specifically probably this one:

    http://manewc.com/2008/09/02/preloading-multiple-image-demo/

    Thanks, and congratulations!

    -Morgan

Continuing the Discussion



Some HTML is OK

or, reply to this post via trackback.