2016-11-14 47 views
3

我不知道我的标题是否可以表示我现在面临的问题。 我会详细解释它:当像素阵列是小的可收集文本时,不会生成8位BMP图像AS3

我从RichEditableTexts生成bmp图像,我使用Bitmap类来获取DisplayObject属性,这将允许我将其作为像素来管理它。

然后,我有这样的功能:

/* 
    * 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; 
    } 

这些是我从使图像的DisplayObject例子:

RichEditableTexts

正在生成第一图像良好,但是第二一个不...

Windows Explorer

如果我打开与原子第二个,看起来是这样的:

enter image description here

为什么? 有人可以看到我失踪的东西......这只是...... ahhh。

预先感谢您:)

+0

你必须使用.BMP?我在过去10年左右没有遇到过。为什么不是.png?有一个内置的编码器:PNGEncoder。 – null

+0

有没有办法做一个8位PNG? @null由于8位,我使用位图,它是一个具有足够灰度信息的超小图像。我通过ftp将这些图像发送到打印机上打印,如果图像较小,但可以保持它的质量将适用于我。 – mariomenjr

+0

这解决了吗?如果不是,你可以提供两个'.bmp'文件的链接(可以检查内部字节以查看代码出错的位置)... –

回答

0

我发现我是不添加垫衬在需要的时候... 这是生成的代码。

private static function encode(bitmapData:BitmapData):ByteArray { 
     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); 
     var imageSize:int  = imageBytes.length; 

     // Offsets 
     var imageDataOffset:int = 0x436; 
     var colorTableOffset:int = 0x36; 

     // Pixel array 
     var col:int = bmpWidth; 
     var row:int = bmpHeight; 
     var rowLength:int = col * bytesPerPixel; // 4 bytes per pixel (32 bit) 

     // Padding 
     var mod:int = (rowLength % 4) != 0 ? 4 - (rowLength % 4):0; 
     rowLength += mod; 

     // File size 
     var fileSize:int = imageSize + imageDataOffset + (mod * row); 

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

     // header information 
     bmpBytes.length = fileSize; 

     // DIB header (40 bytes version) 
     bmpBytes.writeByte(0x42);    // B 
     bmpBytes.writeByte(0x4D);    // M (BMP identifier) 
     bmpBytes.writeInt(fileSize);  // file size 
     bmpBytes.position = 0x0A;    // offset to image data 
     bmpBytes.writeInt(imageDataOffset); 
     bmpBytes.writeInt(0x28);    // header size 
     bmpBytes.position = 0x12;    // width, height 
     bmpBytes.writeInt(bmpWidth); 
     bmpBytes.writeInt(bmpHeight); 
     bmpBytes.writeShort(1);    // planes (1) 
     bmpBytes.writeShort(bitDepth);  // color depth (32 bit) 
     bmpBytes.writeInt(0);     // compression type 
     bmpBytes.writeInt((imageSize + (mod * row)));   // image data size 

     bmpBytes.writeInt(0x2E23);   // Horizontal resolution 
     bmpBytes.writeInt(0x2E23);   // Vertical resolution 

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

     bmpBytes.position = colorTableOffset; // start of color table... 

     /* COLOR TABLE */ 
     for (var i:uint = 0; i < 1024; i++) { 
      bmpBytes.writeByte(i); //B 
      bmpBytes.writeByte(i); //G 
      bmpBytes.writeByte(i); //R 
      bmpBytes.writeByte(0); //A 
     } 

     /* Pixel array */ 
     bmpBytes.position = imageDataOffset; // start of image data... 
     var imgBmp:ByteArray; 
     try { 

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

      // bottom row up 
      while (row--) { 
       imgBmp = new ByteArray(); 

       // from end of file up to imageDataOffset 
       bmpBytes.position = imageDataOffset + row*rowLength; 

       // read through each column writing 
       // those bits to the image in normal 
       // left to rightorder 
       col = bmpWidth; 
       while (col--) { 

        imageBytes.readBytes (imgBmp, 0, 4); 
        bmpBytes .writeBytes(imgBmp, 1, 1); 
       } 
       bmpBytes.position += mod; 
      } 
     }catch(error:Error){ 
      // end of file 
      Alert.show(error.toString(), "EOF"); 
     } 

     // return BMP file 
     return bmpBytes; 
    } 

根据BMP规范,每次行的字节数不是四的倍数,您必须添加填充以解决这个问题。

enter image description here

正如你可以看到我做了这个代码更简单,但如果你能在这几行看到:

// Padding 
var mod:int = (rowLength % 4) != 0 ? 4 - (rowLength % 4):0; 
rowLength += mod; 

根据实际rowLenght我调整我的rowLenght。 然后,后来我只需要“采取数量”额外的字节写入时:

bmpBytes.position += mod; 

当填充字节:

/* Pixel array */ 
bmpBytes.position = imageDataOffset; // start of image data... 
var imgBmp:ByteArray; 
try { 

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

    // bottom row up 
    while (row--) { 
     imgBmp = new ByteArray(); 

     // from end of file up to imageDataOffset 
     bmpBytes.position = imageDataOffset + row*rowLength; 

     // read through each column writing 
     // those bits to the image in normal 
     // left to rightorder 
     col = bmpWidth; 
     while (col--) { 

      imageBytes.readBytes (imgBmp, 0, 4); 
      bmpBytes .writeBytes(imgBmp, 1, 1); 
     } 
     bmpBytes.position += mod; 
    } 
}catch(error:Error){