views:

39

answers:

1

I have a custom Image class that I am using to store individual image information for a gallery application:

package mtm.test
{
 public class Image extends Object
 {
  public var id:int;
  public var filename:String;
  public var title:String;
  public var description:String;

  public var thumbExists:int;
  public var mediumExists:int;
  public var fullExists:int;
 }
}

To manage three different sizes of Bitmaps, I have created the following base class (BitmapType) and three sub-classes (BitmapThumbnail, BitmapMediumSize, BitmapFullSize):

package mtm.test 
 {
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  public class BitmapType extends Bitmap
  {
   public function BitmapType(bitmapData:BitmapData = null, pixelSnapping:String = 'auto', smoothing:Boolean = false)
   {
    super(bitmapData, pixelSnapping, smoothing);
   }
  }
 }

 package mtm.test 
 {
  import flash.display.BitmapData;
  public class BitmapFullSize extends BitmapType 
  { 
   public function BitmapFullSize(bitmapData:BitmapData = null, pixelSnapping:String = 'auto', smoothing:Boolean = false)
   {
    super(bitmapData, pixelSnapping, smoothing);
   }
  }
 }

 package mtm.test 
 {
  import flash.display.BitmapData;
  public class BitmapMediumSize extends BitmapType 
  { 
   public function BitmapMediumSize(bitmapData:BitmapData = null, pixelSnapping:String = 'auto', smoothing:Boolean = false)
   {
    super(bitmapData, pixelSnapping, smoothing);
   }
  }
 }

 package mtm.test 
 {
  import flash.display.BitmapData;
  public class BitmapThumbnail extends BitmapType 
  {
   public function BitmapThumbnail(bitmapData:BitmapData = null, pixelSnapping:String = 'auto', smoothing:Boolean = false)
   {
    super(bitmapData, pixelSnapping, smoothing);
   }
  }
 }

This is how I would implement the above:

var image:Image = new Image();

//I would be loading external bitmaps but for the example I'll just create new ones:
image[BitmapThumbnail] = new BitmapThumbnail(new BitmapData(65,65,false,0x000000));
image[BitmapMediumSize] = new BitmapMediumSize(new BitmapData(200,200,false,0x000000));
image[BitmapFullSize] = new BitmapFullSize(new BitmapData(500,500,false,0x000000));

Is there a simpler way to do this? I feel that there is a lot of repeated code within the BitmapType sub-classes.

At the least, this helps to avoid a bunch of for loops trying to find the requested size, and it seems portable to situations where more or less sizes of Bitmaps are required.

+1  A: 

you could simply use a cache and have it filled on demand. here's a sketch:

class Image {
    var url:String;
    //... other stuff
    var cache:Object = {};
    function getImage(size:int, onDone:Function, onProgress:Function = null, onError:Function = null):void {
        if (onProgress == null) onProgress = function (loaded:int, total:int):void {};
        var cached:* = this.cache[size];
        if (cache == null) {
            var l:Loader = new Loader();
                    var req:URLRequest = new URLRequest(url)
            //add parameters here, depending on size
            l.load();
            l.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
                onError(cache[size] = e);
            });
            l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, function (p:ProgressEvent):void {
                onProgress(p.byteLoaded, p.byteTotal);
            });
            l.contentLoaderInfo.addEventListener(Event.COMPLETE, function (e:Event):void {
                onDone(cache[size] = l.content);
            });
        }
        else if (cache is DisplayObject) {
            onDone(cache);
        }
        else onError(cache);
    }
}

hypothetical example usage:

myImage.getImage(ImageSize.THUMB, displayImage, updateLoader, displayBroken);
back2dos
That is a great idea. I actually meant size as in "dimensions" but I should have been more specific. I guess it is safe to assume that the larger (in dimension) images will have a larger file size, so this would probably work!
letseatfood
@letseatfood: you could do something as `sizes = [{width:50,height:50},{width:100, size:100},...]` and let `size` simply be an index into that array.
back2dos
@back2dos - Your solution is really great, but since the byte size or the dimension won't work as an index for me (the dimensions are variable), I ended up creating a `sizes:Object` property on my `Image` class and then an `ImageSizes` class that extends Object. I then created some constants within `ImageSizes` and am using those constants to index the different image sizes.
letseatfood
@back2dos - I would give you more vote-ups if I could, your "sketch" is brilliant.
letseatfood
@letseatfood: ok. I'm not sure I fully understand how sizes are meant to work (sounds a little overengineered to me), but I'm happy to hear my idea works for you ;)
back2dos
@back2dos - Yeah I think it is over-engineered too, but I can't seem to simplify it and just need to get it done and move one :-)
letseatfood