Search Box

Google
 

Sunday, February 11, 2007

BitmapData.........

Hai all,

i am back after a very long long time. But happy i am back atleast now. Today we shall discuss about caching image using BitmapData class. Actually "bitmapdata" is a new class that has been introduced for flash player 8. What this class can do is enormous, but we are here to discuss today what it can do for caching dynamically loaded images.

I was always wondering how can i stop those reloading of images again and again, until i was introduced to the BitmapData class by a colleague of mine who recently discovered this. After playing around with the class for sometime an idea struck to me for solving the problem of reloading the loaded images with BitmapData class being the key. This solution ultimately gave birth to a class "ImageCache" which looks after the images loaded using it and ultimately returns a BitmapData which can be attached to the image holding movieClip using attachBitmap() method.

The content of the class goes like this :

import flash.display.BitmapData

class ImageCache
{
/**
@ varible __paths
@ description: The array that holds the path of the images loaded.
*/
private var __paths:Array;

/**
@ varible loader
@ description: MovieClip that holds the images to be loaded and cached.This is a temporary movieClip.
*/
private var loader:MovieClip;


/**
@ method ImageCache
@ description: Constructor Function.
*/
public function ImageCache()
{
__paths = new Array();
}

/**
@ method registerTempLoader
@ arguments : None;
@ access : Public
@ returns : Nothing.
@ description: Method that registers a valid MovieClip to be used for caching Images.
*/
public function registerTempLoader(mc:MovieClip):Void
{
loader = mc;
}


/**
@ method : cacheImage
@ arguments : String path , float Width, float Height;
@ access : Public
@ returns : BitmapData.
@ description : When a path is passed into the argument along with the width and height
loads the image and returns the cached image as a BitmapData.
*/
public function cacheImage(path:String,w:Number,h:Number):BitmapData
{
var index:Number = isCached(path);
if( index < 0)
{
var obj:Object = new Object();
var mc:MovieClip = loader.createEmptyMovieClip('loader'+__paths.length,__paths.length);
obj.path = path;
obj.bdata = new BitmapData((w==undefined)?100:w,(h==undefined)?100:h,false,0xcc33ff);
mc.loader = new MovieClipLoader();
mc.loader.addListener(this);
mc.loader.loadClip(path,mc.createEmptyMovieClip('loader',0));
mc.index = __paths.length;
__paths.push(obj);
return obj.bdata;
}
else
{
return __paths[index].bdata;
}

}


/**
@ method : isCached
@ arguments : String path;
@ returns : Number.
@ access : Private
@ description : When a path is passed into the argument checks from the
__paths array if the path is already loaded returns the
index of the path in the array else returns -1.
*/
private function isCached(path:String):Number
{
for(var i:Number=0;i<__paths.length;i++)
{
if(__paths[i].path == path)
{
return i;
}
}
return -1;
}


/**
@ method : onLoadInit
@ arguments : target MovieClip;
@ returns : Nothing.
@ access : Private
@ description : When an image loads successfully its parent get drawn using BitmapData.
*/
private function onLoadInit(target:MovieClip):Void
{
__paths[target._parent.index].bdata.draw(target._parent);
}
}



Okay, the class is written but how do we use it ??? Nice Question !

i had developed a image gallery using this class believe me. i will paste the actionscript that exists in the timeline of the stage as given below. But before that have two things ready in the library. one is a macromedia scrollpane and the next is create two empty movieclips with one having a linkage name "thumbHolder" and the other empty movieclip does not require any linkage ids.

Now drag the ScrollPane to the stage and name it "$spane" with the content path in the parameters field as "thumbHolder". Now drag the empty movieClip without any linkage id to the stage and name it "$main".

Then paste the below actions on the first frame of the Stage.


//Instance of the ImageCache Class.
var iCache:ImageCache = new ImageCache();

//Temporary images holder.
var imageHolder:MovieClip = this.createEmptyMovieClip('tempImageHolder',0);


//The thumbnal images holder
var galleryHolder:MovieClip = $spane.spContentHolder.createEmptyMovieClip('thumbNailholder',1);


//The main picture holder.
var mainPicture:MovieClip = $main.createEmptyMovieClip('mainLoader',0);

var width:Number = 360;//Width value - change at your will.

var height:Number = 480;//Height value - change at your will.

//The below function is the one that starts to cache images.
function cacheImages():Void
{
var ratio:Number = 360/480;
var thumbHeight:Number = 480/4;
var thumbHolder:MovieClip = galleryHolder.createEmptyMovieClip('holder',0);
for(var i:Number=0;i<19;i++)
{
var index:Number = 787 + i;
var path:String = 'images/SP_A0'+index+'.jpg';//Change this value to your custom image path
var thumb:MovieClip = thumbHolder.createEmptyMovieClip('gal'+i,i);
thumb.createEmptyMovieClip('loader',0).attachBitmap(iCache.cacheImage(path,360,480),0);
thumb.loader._width = ratio * thumbHeight;
thumb.loader._height = thumbHeight;
thumb._y = (thumbHeight+5) * i;
thumb.path = path;
thumb.onPress = function()
{
mainPicture.attachBitmap(iCache.cacheImage(this.path,360,480),0);
//mainPicture.createEmptyMovieClip('loader',0).loadMovie(this.path);
}
}
$spane.redraw(1);
}
imageHolder._visible = false;//setting the visiblity of the tempimages holder to false.

imageHolder._x = 100000;//setting the distance of the tempimages holder to a large one so we cannot see it.


iCache.registerTempLoader(imageHolder);//REgsitering the tempImage Holder as the loader for caching images.


cacheImages();//Start Caching Images.


So having restarted my blogging with the BitmapData class makes me feel a bit enthus !!!!

Thanks for reading.

Regards,

Ashok Srinivasan.