package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.display.Graphics; import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.HTTPStatusEvent; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.geom.Point; import flash.geom.Rectangle; import flash.net.URLRequest; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; import flash.utils.getTimer; public class ReadJPNG extends Sprite { private var rgbLoader:Loader; private var rgbLoaded:Boolean; private var rgbLoadError:Boolean; private static const RGB_LOCATION:String = "./rgb.jpg"; private var alphaLoader:Loader; private var alphaLoaded:Boolean; private var alphaLoadError:Boolean; private static const ALPHA_LOCATION:String = "./alpha.png"; private var console:TextField; private var bitmap:Bitmap = new Bitmap(); //Transparency patern private static const TRANSPARENT:BitmapData = new BitmapData(16, 16, false, 0xffffff); { TRANSPARENT.fillRect(new Rectangle(0, 0, 8, 8), 0xcccccc); TRANSPARENT.fillRect(new Rectangle(8, 8, 8, 8), 0xcccccc); } public function ReadJPNG():void { this.stage.align = StageAlign.TOP_LEFT; this.stage.scaleMode = StageScaleMode.NO_SCALE; this.console = new TextField(); this.console.embedFonts = true; this.console.defaultTextFormat = new TextFormat("CodingFontTobi", 16); this.console.autoSize = TextFieldAutoSize.LEFT; this.addChild(this.bitmap); this.addChild(this.console); this.rgbLoader = new Loader(); this.rgbLoader.load(new URLRequest(this.stage.loaderInfo.parameters.rgb || RGB_LOCATION)); this.rgbLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.checkImageLoadingStatus, false, 0, true); this.rgbLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.checkImageLoadingStatus, false, 0, true); this.rgbLoader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, this.checkImageLoadingStatus, false, 0, true); this.rgbLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, this.checkImageLoadingStatus, false, 0, true); this.rgbLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.imageLoadComplete, false, 0, true); this.rgbLoaded = false; this.rgbLoadError = false; this.alphaLoader = new Loader(); this.alphaLoader.load(new URLRequest(this.stage.loaderInfo.parameters.alpha || ALPHA_LOCATION)); this.alphaLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.checkImageLoadingStatus, false, 0, true); this.alphaLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.checkImageLoadingStatus, false, 0, true); this.alphaLoader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, this.checkImageLoadingStatus, false, 0, true); this.alphaLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, this.checkImageLoadingStatus, false, 0, true); this.alphaLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.imageLoadComplete, false, 0, true); this.alphaLoaded = false; this.alphaLoadError = false; this.stage.addEventListener(Event.RESIZE, this.layOut); this.stage.dispatchEvent(new Event(Event.RESIZE)); } private function layOut(event:Event):void { //Draw transparency partern var graphics:Graphics = this.graphics; graphics.clear(); graphics.beginBitmapFill(TRANSPARENT, null, true, false); graphics.drawRect(0, 0, this.stage.stageWidth, this.stage.stageHeight); graphics.endFill(); this.console.width = this.stage.stageWidth; this.bitmap.x = (this.stage.stageWidth - this.bitmap.width) / 2; this.bitmap.y = (this.stage.stageHeight - this.bitmap.height) / 2; } private function log(value:String):void { this.console.appendText(value + "\n"); } //Check loading status for error handling private function checkImageLoadingStatus(event:Event):void { var errorOccured:Boolean = false; var loaderInfo:LoaderInfo = event.currentTarget as LoaderInfo; switch(event.type) { case HTTPStatusEvent.HTTP_STATUS: var status:int = (event as HTTPStatusEvent).status; if(status >= 400)// Client and server errors// If the resource is not directly accessible { this.log("Loading error: HTTP status error: " + status); errorOccured = true; loaderInfo.loader.close(); } break; case IOErrorEvent.IO_ERROR: this.log("Loading error: " + (event as IOErrorEvent).text); errorOccured = true; break; case SecurityErrorEvent.SECURITY_ERROR: this.log("Loading error: " + (event as SecurityErrorEvent).text); errorOccured = true; break; } if (errorOccured) { log("Loading error, can't proceed: " + loaderInfo.url); if (loaderInfo == this.rgbLoader.contentLoaderInfo) this.rgbLoadError = true; else if (loaderInfo == this.alphaLoader.contentLoaderInfo) this.alphaLoadError = true; } } private function imageLoadComplete(event:Event):void { var loader:Loader = (event.currentTarget as LoaderInfo).loader; if (loader == this.rgbLoader) { this.rgbLoaded = true; this.log("RGB Loaded: " + loader.contentLoaderInfo.bytesTotal + " bytes"); } else if (loader == this.alphaLoader) { this.alphaLoaded = true; this.log("Alpha Loaded: " + loader.contentLoaderInfo.bytesTotal + " bytes"); } //When both are loaded, merge it if (this.rgbLoaded && this.alphaLoaded) { var alpha:BitmapData; var rgb:BitmapData; var argb:BitmapData; try { alpha = (this.alphaLoader.content as Bitmap).bitmapData; try { rgb = (this.rgbLoader.content as Bitmap).bitmapData; } catch(error:Error) { this.log("Merge rgb with alpha fail: " + error.message); } } catch(error:Error) { this.log("Merge alpha with rgb fail: " + error.message); } if(alpha && rgb)//Need valid images { var time:uint = getTimer(); //Loaded bitmapData are not transparent argb = new BitmapData(rgb.width, rgb.height, true, 0x00000000); //Copy RGB argb.copyPixels ( rgb, new Rectangle(0, 0, rgb.width, rgb.height), new Point(0, 0) ) //Apply alpha channel argb.copyChannel ( alpha, new Rectangle(0, 0, alpha.width, alpha.height), new Point(0, 0), BitmapDataChannel.RED,//r = g = b = gray BitmapDataChannel.ALPHA ); //Free memory of loaded images rgb.dispose(); alpha.dispose(); this.log("Merge successfull: " + argb.width + "px * " + argb.width + "px in " + (getTimer() - time) + " ms"); this.bitmap.bitmapData = argb; this.stage.dispatchEvent(new Event(Event.RESIZE)); } } } } }