lundi 14 novembre 2016

8 bit BMP image not generated when pixel array is to small richeditable text AS3

I don't know if my title can express the issue I am facing right now. I'll explain it in detail:

I am generating bmp images from RichEditableTexts, I am using the Bitmap class to get the DisplayObject properties that will allow me to manage it as Pixels.

Then I have this function:

    /*
     * Create a 8 bit BMP image as bytearray, with 256 color ( grayscale ).
     * 
    */
    private static function encode( bitmapData:BitmapData ):ByteArray {
        // bit depth configuration
        var bytesPerPixel:int = 1;
        var bitDepth:int = 8;

        // image/file properties
        var bmpWidth:int         = bitmapData.width;
        var bmpHeight:int        = bitmapData.height;
        var imageBytes:ByteArray = bitmapData.getPixels( bitmapData.rect );

        /* Image from Preview size */
        var imageSize:int = bmpWidth * bmpHeight * bytesPerPixel;

        /* Image offset */
        var imageDataOffset:int = 0x436;

        /* File size */
        var fileSize:int = imageSize + imageDataOffset;

        // binary BMP data
        var bmpBytes:ByteArray = new ByteArray();
        bmpBytes.endian = Endian.LITTLE_ENDIAN; // byte order

        // header information
        bmpBytes.length = fileSize;
        bmpBytes.writeByte(0x42);             // B                   //0
        bmpBytes.writeByte(0x4D);             // M (BMP identifier)  //1
        bmpBytes.writeInt(fileSize);          // file size           //2
        bmpBytes.position = 0x0A;             // offset to image data
        bmpBytes.writeInt( imageDataOffset );                        //10 4 Bytes
        bmpBytes.writeInt(0x28);              // header size         //14 4 Bytes
        bmpBytes.position = 0x12;             // width, height        
        bmpBytes.writeInt( bmpWidth );                             //18 4 Bytes
        bmpBytes.writeInt( bmpHeight );                            //22 4 Bytes
        bmpBytes.writeShort( 1 );             // planes (1)        //26 2 Bytes
        bmpBytes.writeShort( bitDepth );      // color depth       //28 2 Bytes
        bmpBytes.writeInt( 0 );               // compression type  //30 4 Bytes 
        bmpBytes.writeInt( imageSize );       // image data size   //34 4 Bytes 

        bmpBytes.writeInt( 0x2E23 );          // Horizontal resolution //38 4 Bytes
        bmpBytes.writeInt( 0x2E23 );          // Vertical resolution   //42 4 Bytes

        bmpBytes.writeInt( 0x100 );           // Color in the palette

        bmpBytes.position = 0x36;             // start of color table

        /* COLOR TABLE */
        var table:uint = 256 * 4;
        for (var i:uint = 0; i < table; i++) {
            bmpBytes.writeByte( i ); //B
            bmpBytes.writeByte( i ); //G
            bmpBytes.writeByte( i ); //R
            bmpBytes.writeByte( 0 ); //A
            /*
             * Grays are made of equal bytes, for example: #AAAAAA is gray. 
            */
        }

        bmpBytes.position = imageDataOffset; // start of image data... byte 310 // 1078

        // write pixel bytes in upside-down order
        // ( as per BMP format )
        var col:int = bmpWidth;
        var row:int = bmpHeight;
        var rowLength:int = col * bytesPerPixel; // Bytes per column based on Bit depth

        // Writing bytes to new image vars
        var writingOffset:int = 4 - ( bitDepth / 8 );

        try {               
            // make sure we're starting at the
            // beginning of the image data
            imageBytes.position = 0;

            // Tmp ByteArray to extract 32 bits per pixel 
            var tmpBytes:ByteArray;

            // bottom row up
            while (row--) {
                /* hey += "LINE\n"; */

                // from end of file up to imageDataOffset
                tmpBytes = new ByteArray();
                bmpBytes.position = imageDataOffset + ( row * rowLength );

                // read through each column writing
                // those bits to the image in normal
                // left to rightorder
                col = bmpWidth;
                while (col--) {
                    // Extracting the 32 bits corresponding 
                    // to a pixel per getPixels method ( always the same ).
                    imageBytes.readBytes( tmpBytes, 0, 4 );

                    // We just need one BYTE of the 4 that are in this array.
                    tmpBytes.position = 3;

                    // THIS IS THE INDEX ON OUR COLOR TABLE ( GRAYSCALE ). 
                    bmpBytes.writeByte( tmpBytes.readUnsignedByte() );
                }
            }
        } catch(error:Error) {
            // end of file
            Alert.show( error.toString(), "I/O BMP ERROR" );
        }

        // return BMP file
        return bmpBytes;
    }

These are to examples of the DisplayObjects I am making images from:

RichEditableTexts

The first image is being generated good, but the second one no...

Windows Explorer

If I open the second one with atom, looks like this:

enter image description here

Why? Can someone see something I am missing... this is just... ahhh.

Thank you in advance :)

Aucun commentaire:

Enregistrer un commentaire