LOAD *.BMP – AS3

November 17, 2009 at 2:39 PM (Actionscript)

Trying to load a bmp file in runtime using the byteArray, may not be a perfect code but helped me to learn handling image formats and byteArray class…..playing with byteArray is becoming more and more fun

This code supports only 16,24,32 bit uncompressed bmp images

package {
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.display.*;
	import flash.display.BitmapData;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.geom.Matrix;
	public class BmpDecoder extends Sprite {
		private var urlLoader:URLLoader;
		private var barr:ByteArray;
		var pixData:ByteArray;
		var canvas:MovieClip;
		public function BmpDecoder(url) {
			urlLoader=new URLLoader  ;
			urlLoader.dataFormat=URLLoaderDataFormat.BINARY;
			urlLoader.addEventListener(Event.COMPLETE,onComplete);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR,onError);
			urlLoader.load(new URLRequest(url));
			canvas=new MovieClip;
			addChild(canvas);
		}
		private function onComplete(e:Event):void {
			var data:ByteArray=urlLoader.data;
			urlLoader.data=null;
			urlLoader.close();
			urlLoader=null;
			decodeBMP(data);
		}
		private function onError(e:Event):void {
			trace("Error");
		}
		private function getPixelCol() {
			var r,g,b,rs,gs,bs;
			bs=pixData.readUTFBytes(1).toString();
			if (bs.length == 0) {
				b='00';
			} else {
				b=bs.charCodeAt(0).toString(16);
			}
			gs=pixData.readUTFBytes(1).toString();
			if (gs.length == 0) {
				g='00';
			} else {
				g=gs.charCodeAt(0).toString(16);
			}
			rs=pixData.readUTFBytes(1).toString();
			if (rs.length == 0) {
				r='00';
			} else {
				r=rs.charCodeAt(0).toString(16);
			}
			return Number('0x' + r + g + b);
		}
		private function rgb16to32(bit16) {
			var r=bit16 & 0x7C00 >> 10;
			var g=bit16 & 0x3E0 >> 5;
			var b=bit16 & 0x1F;
			r=r << 3;
			g=g << 3;
			b=b << 3;
			return [b,g,r,0];
		}
		private function convert24To32(n,w) {
			var tempArr:ByteArray=new ByteArray;
			tempArr.endian="littleEndian";
			pixData.position=0;
			var debug="";
			var by=n / 8;
			var pad=by * w % 4;
			pad=pad?4 - pad:pad;
			var xc=1;
			while (pixData.bytesAvailable > by) {
				if (xc == w + 1) {
					xc=1;
					for (var j=0; j < pad; j++) {
						pixData.readByte();
					}
				}
				if (pixData.bytesAvailable < by) {
					break;
				}
				pixData.readBytes(tempArr,tempArr.length,by);
				tempArr.position=tempArr.length;
				tempArr.writeByte(0);
				xc++;
			}
			pixData.position=0;
			tempArr.position=0;
			return tempArr;
		}
		private function convert16To32(n,w) {
			var tempArr:ByteArray=new ByteArray;
			tempArr.endian="littleEndian";
			pixData.position=0;
			var debug="";
			var by=n / 8;
			var pad=by * w % 4;
			pad=pad?4 - pad:pad;
			var xc=1;
			while (pixData.bytesAvailable > by) {
				if (xc == w + 1) {
					xc=1;
					for (var j=0; j < pad; j++) {
						pixData.readByte();
					}
				}
				if (pixData.bytesAvailable < by) {
					break;
				}
				var bit16=pixData.readUnsignedShort();
				var bit32=rgb16to32(bit16);
				tempArr.position=tempArr.length;
				tempArr.writeByte(bit32[0]);
				tempArr.writeByte(bit32[1]);
				tempArr.writeByte(bit32[2]);
				tempArr.writeByte(bit32[3]);
				xc++;
			}
			pixData.position=0;
			tempArr.position=0;
			return tempArr;
		}
		private function decodeBMP(arr:ByteArray) {
			barr=arr;
			barr.endian="littleEndian";
			var isBitmap=barr.readUTFBytes(2) == "BM";
			var fsize,r1,r2,off,infoL,w,h,cp,bpp,comp,raw,xR,yR,pal,ic;
			pixData=new ByteArray  ;
			pixData.endian="littleEndian";
			if (isBitmap) {
				fsize=barr.readUnsignedInt();
				r1=barr.readShort();
				r2=barr.readShort();
				off=barr.readUnsignedInt();
				infoL=barr.readUnsignedInt();
				w=barr.readInt();
				h=barr.readInt();
				cp=barr.readShort();// # of color planes.
				bpp=barr.readShort();// # bits per pixel.
				comp=barr.readUnsignedInt();// No compresion.
				raw=barr.readUnsignedInt();// Size of the raw image data.0 is valid for no compression.
				xR=barr.readInt();// x resolution
				yR=barr.readInt();// y resolution
				pal=barr.readUnsignedInt();// # of colors in color pallete. 0 indicates default 2^n.
				ic=barr.readUnsignedInt();// # of important colors. what?
				var pp=barr.position;
				var len=barr.bytesAvailable;
				var pad=len % 3;
				len=len - pad;
				//barr.position=off
				barr.readBytes(pixData,0,off - 54);
				if (bpp == 24) {
					pixData=convert24To32(bpp,w);
				} else if (bpp == 16) {
					pixData=convert16To32(bpp,w);
				}
				pixData.position=0;
				var rect:Rectangle=new Rectangle(0,0,w,h);
				var bmpData:BitmapData=new BitmapData(w,h,! true,0xffffff);

				var tmpBmp:BitmapData=bmpData.clone();
				tmpBmp.setPixels(rect,pixData);
				//in bmp format pixels are stored from bottom left to top
				//-so it will be displayed inverted so while reading data itself
				//-you can read from bottom to top rather than the method im adopting
				var mat:Matrix=new Matrix;
				mat.scale(1,-1);
				mat.translate(0,h);
				bmpData.draw(tmpBmp,mat,null,null,null,true);
				var bmp:Bitmap=new Bitmap(bmpData);
				bmp.smoothing=true;
				canvas.addChild(bmp);
			} else {
				trace("NOT A BITMAP FILE");
			}
		}
	}
}
Advertisements

Permalink Leave a Comment

Next page »

%d bloggers like this: