/* * Class written by Xavier MARTIN (xxlm or zeflasher) * http://dev.webbymx.net * http://www.webbymx.net * If you are using this class, I will be glad to receive a picture of you front of your city hall ( or wherever outside ) * To do so please visit http://dev.webbymx.net and go in the about page to get my details... * Licence: http://creativecommons.org/licenses/by-nc-sa/2.0/fr/deed.en */ import flash.display.BitmapData; import net.webbymx.files.Hexa; class net.webbymx.files.binary.BitmapDataExporter { /* **************************************************************************** * PRIVATE VARIABLES **************************************************************************** */ private var _bmp : BitmapData; private var _nWidth : Number; private var _nHeight : Number; private var _nRemainder : Number; private var _nCurrentStep : Number; private var _nStepLength : Number; private var _nTotalSteps : Number; private var _mcEnterFrame : MovieClip; /* **************************************************************************** * PUBLIC VARIABLES **************************************************************************** */ public var onProgress : Function; public var onExportDone : Function; /* **************************************************************************** * CONSTRUCTOR **************************************************************************** */ function BitmapDataExporter( b : BitmapData ) { _init( b ); } private function _init( b : BitmapData ) : Void { _bmp = b; _nWidth = _bmp.width; _nHeight = _bmp.height; _nCurrentStep = 0; _nRemainder = _nWidth % 4; _nTotalSteps = Math.ceil( _nWidth * _nHeight / 900 ); _nStepLength = Math.ceil( _nWidth * _nHeight / _nTotalSteps / 2 ) * 2; } /* **************************************************************************** * PRIVATE FUNCTIONS **************************************************************************** */ /** * Return a string of hexa for the file header * @param Void * @return */ private function _fileHeader( Void ) : Void { var bin : String = ""; /* * bfType1 : Byte ; (* "B" *) * bfType2 : Byte ; (* "M" *) * bfSize : LongInt ; (* Size of File. Zero is acceptable *) * bfReserved1 : Word ; (* Zero *) * bfReserved2 : Word ; (* Zero *) * bfOffBits : LongInt ; (* Offset to beginning of BitMap *) */ // writing the file type ( B and M == 42 and 4D ) bin = "424D"; // writing size ( longInt ) bin += "00000000"; // writing reserved, reserved ( word ) bin += "00000000"; // writing Offset to beginning of BitMap ( longInt ) bin += "36000000"; onProgress( bin ); } private function _bitmapHeader( Void ) : Void { var bin : String = ""; var wh : String = Hexa.getDWord( _nWidth.toString( 16 ) ) var hh : String = Hexa.getDWord( _nHeight.toString( 16 ) ) /* * biSize : LongInt ; (* Number of Bytes in Structure *) * biWidth : LongInt ; (* Width of BitMap in Pixels *) * biHeight : LongInt ; (* Height of BitMap in Pixels *) * biPlanes : Word ; (* Planes in target device = 1 *) * biBitCount : Word ; (* Bits per Pixel 1, 4, 8, or 24 *) * biCompression : LongInt ; (* BI_RGB = 0, BI_RLE8, BI_RLE4 *) * biSizeImage : LongInt ; (* Size of Image Part (often ignored) *) * biXPelsPerMeter : LongInt ; (* Always Zero *) * biYPelsPerMeter : LongInt ; (* Always Zero *) * biClrUsed : LongInt ; (* Number of Colors used in Palette *) * biClrImportant : LongInt ; (* Number of Colors that are Important *) */ // writing Number of Bytes in Structure ( longInt ) bin = "28000000"; // writing width & height bin += wh + hh; // writing planes bin += "0100"; // writing bitcounts bin += "1800"; // writing compression bin += "00000000"; // writing Size Image bin += "00000000"; // writing biXPelsPerMeter bin += "00000000"; // writing biYPelsPerMeter bin += "00000000"; // writing biClrUsed bin += "00000000"; // writing biClrImportant bin += "00000000"; onProgress( bin ); } private function _buildData( Void ) : Void { // local access of the function -> speed improvement var getString : Function = Hexa.getString; // string where the hexa is saved var row : String = ""; // The extracted pixel var pix1 : Number; var pix2 : Number; var pix3 : Number; // The max value to consider in the local for loop var maxPix : Number = Math.min( ( _nCurrentStep + 1 ) * _nStepLength, _nWidth * _nHeight); // writing data for( var i : Number = _nCurrentStep * _nStepLength; i < maxPix; i += 2 ) { // The pixel to examine pix1 = _bmp.getPixel( i % _nWidth, ( _nHeight - 1 ) - Math.floor( i / _nWidth ) ); pix2 = _bmp.getPixel( (i + 1) % _nWidth, ( _nHeight - 1 ) - Math.floor( (i + 1) / _nWidth ) ); if( i % _nWidth == 0 && i !=0 ) for ( var r : Number = 0; r < _nRemainder; ++r ) row = row + "00"; row += getString( pix1.toString( 16 ), 6 ); if( ( i + 1 ) % _nWidth == 0 && ( i + 1 ) >= _nWidth ) for ( var r : Number = 0; r < _nRemainder; ++r ) row += "00"; row += getString( pix2.toString( 16 ), 6 ); } onProgress( row, ( _nCurrentStep / _nTotalSteps * 100 ) ); } /* **************************************************************************** * PUBLIC STATIC FUNCTIONS **************************************************************************** */ /** * Return the string of hexa to be written in a file or sent * @param b * @param p */ public function export( Void ) : Void { // reference to the instance var owner : BitmapDataExporter = this; // get the file header _fileHeader(); // get the bitmap header _bitmapHeader(); // create the mc holding the enter frame ( the player will not freeze ) _mcEnterFrame = _root.createEmptyMovieClip( "mc_BitmapDataExporter", 98765 ) // build the data onEnterFrame ( do not freeze the player ) _mcEnterFrame.onEnterFrame = function () { // get the data if ( owner._nCurrentStep <= owner._nTotalSteps ) { owner._buildData(); owner._nCurrentStep++; } else { owner.onExportDone(); this.removeMovieClip() } } } }