建站学 - 轻松建站从此开始!

建站学-个人建站指南,网页制作,网站设计,网站制作教程

当前位置: 建站学 > 图像设计 > Flash教程 >

通过ActionScript分析和显示BMP文件

时间:2012-05-10 13:51来源: 作者: 点击:
我没有经过一个正式的计算机科学培训/教育,所以我从来没有机会了解低层数据结构(比特和字节)工作机制。这一段时间我一直都想学习些这面的知识,但是很难找到相关资源,在不假设我有一个计算机科学学士学位的情况下。 昨天,FITC提交了“多伦多FITC所有视频会议&rdquo

我没有经过一个正式的计算机科学培训/教育,所以我从来没有机会了解低层数据结构(比特和字节)工作机制。这一段时间我一直都想学习些这面的知识,但是很难找到相关资源,在不假设我有一个计算机科学学士学位的情况下。
昨天,FITC提交了“多伦多FITC所有视频会议”,我花了一些时间观看Lee Brimelow介绍的ByteArrays工作机制。他提供了明确而可靠的基础和理解ByteArrays和比特字节的工作机制。
不管怎么说,在看到Lee的会议后,我终于一切都安定了,昨晚花了些时间组建一个简单的解析器,在Flash中动态加载和显示一个24位BMP图像。
我将代码连同完整的意见随后张贴,提供一个简单的示例,向对较低级别的文件格式感兴趣的朋友做一个解释。
该代码需要Adobe AIR环境(所以我可直接加载BMP)。为了转换成浏览器中Flash Player可识别的,只需要替换文件调用FileReference.browse加载。

   1. package
   2. {
   3.         import flash.filesystem.File;
   4.         import flash.filesystem.FileStream;
   5.         import flash.filesystem.FileMode;
   6.

   7.         import flash.display.Sprite;
   8.         import flash.display.BitmapData;
   9.         import flash.display.Bitmap;
  10.         import flash.utils.Endian;
  11.

  12.         import flash.geom.Rectangle;
  13.

  14.         [SWF(width='550', height='400', backgroundColor='#FFFFFF', frameRate='12')]
  15.         public class BMPViewer extends Sprite
  16.         {
  17.                 private static const MAGIC_NUMBER:String = "BM";
  18.                 private static const BMP_DATA_OFFSET_POSITION:int = 0xA;
  19.                 private static const WIDTH_POSITION:int = 0x12;
  20.                 private static const HEIGHT_POSITION:int = 0x16;
  21.

  22.                 public function BMPViewer()
  23.                 {
  24.                         loadBMP();
  25.                         super();
  26.                 }
  27.

  28.                 /*
  29.                         Loads and reads a 24 Bit bitmap file.加载读取24位BMP文件
  30.                       
  31.                         Based on BMP info from:
  32.                         http://en.wikipedia.org/wiki/BMP%5Ffile%5Fformat
  33.                 */
  34.                 private function loadBMP():void
  35.                 {
  36.                         //Load BMP. This requires AIR.加载BMP。需要AIR
  37.                         //Use FileReference.browse for在Flash Player中用FileReference.browse
  38.

  39.                         //Flash Player
  40.                         var bmpFile:File = new File("app:/image.bmp");
  41.                         var fs:FileStream = new FileStream();
  42.

  43.                         //BMP files are Little Endian, which means their BMP采用little-endian存储机制
  44.                         //least significant byte is first (right to left) 第一位是最低有效字节(从右到左)
  45.                         fs.endian = Endian.LITTLE_ENDIAN;
  46.

  47.                         //open the file in READ mode打开文件至读取模式
  48.                         fs.open(bmpFile, FileMode.READ);
  49.

  50.                         //check the first two bytes to make sure
  51.                         //it is a valid BMP file检测BMP是否有效
  52.                         if(fs.readUTFBytes(2) != MAGIC_NUMBER)
  53.                         {
  54.                                 trace("FAIL : NOT A BMP FILE");
  55.

  56.                                 //not a BMP file, close steam
  57.                                 //and exit非BMP关闭流退出
  58.                                 fs.close();
  59.                                 return;
  60.                         }
  61.

  62.                         //note, we could also grab the length from the
  63.                         //header and make sure the file was the correct
  64.                         //length注意,我们还可以从头部抓取长度,并确保该文件长度是正确的
  65.

  66.                         //change the cursors position to the point
  67.                         //in the header that contains the value / offset
  68.                         //of where the actual bitmap data begins
  69.                         //read in the 4 Bytes that contain the value                        fs.position = BMP_DATA_OFFSET_POSITION;
  70.                         var dataPosition:int = fs.readInt();
  71.

  72.                         //set cursor position to where the BMP
  73.                         //width is stored
  74.                         fs.position = WIDTH_POSITION;
  75.

  76.                         //read in the 4 Bytes that contain the width
  77.                         var bmpWidth:int = fs.readInt();
  78.

  79.                         //read in the 4 Bytes that contain the height
  80.                         var bmpHeight:int = fs.readInt();
  81.

  82.                         //set cursor to where the BMP pixel data begins
  83.                         fs.position = dataPosition;
  84.

  85.                         var row:int = 0;
  86.                         var column:int = 0;
  87.

  88.                         //every row length in a BMP file must bee a multiple
  89.                         //of 4 (see the spec). So, we need to determine how much
  90.                         //padding we need to add at the end of each line.
  91.                         var padding:int = (bmpWidth % 4);
  92.

  93.                         //create a fixed length Vector to store the pixel
  94.                         //values as we read them.
  95.                         var pixels:Vector.<uint> = new Vector.<uint>(bmpWidth * bmpHeight, true);
  96.

  97.                         //loop through data (rows and columns)
  98.                         //note that data stored in BMP is backwards to Flash and is
  99.                         //stored from bottom row up, not top row down.
 100.                         //So we have to loop backwards
 101.                         var counter:int = 0;
 102.                         for(var i:int = bmpHeight; i > 0; i--)
 103.                         {
 104.                                 for(var k:int = 0; k < bmpWidth; k++)
 105.                                 {
 106.

 107.                                         var position:int = ((i - 1) * bmpWidth) + k;
 108.                                         /*
 109.                                                 This is the original code that I had which works fine
 110.                                                 but is not as effecient as what I have now.
 111.                                               
 112.                                                 Basically, Pixels are stored within 3 sucessive Bytes
 113.                                                 in a BMP file, with one Byte each for Blue, Green and
 114.                                                 Red values (in that order).
 115.                                               
 116.                                                 So, this reads the Bytes for each pixel, one at a time
 117.                                                 and then combines them into a single value which is
 118.                                                 the combined RGB pixel value.
 119.                                               
 120.                                                 I left the code as I think it make it a little easier to
 121.                                                 understand what is going on, as well as how some of these
 122.                                                 calls can be optimized.
 123.                                         */
 124.

 125.                                         /*
 126.                                         var blue:int = fs.readUnsignedByte();
 127.                                         var green:int = fs.readUnsignedByte();
 128.                                         var red:int = fs.readUnsignedByte();
 129.                                       
 130.                                         pixels[position] = (red << 16 ^ green << 8 ^ blue);
 131.                                         */
 132.

 133.                                         /*
 134.                                                 Here is the final code which is more efficient, as it only
 135.                                                 needs to make 2 read calls in order to get the values.
 136.                                               
 137.                                                 Thanks to Thibault Imbert (bytearray.org) for pointing out
 138.                                                 and helping me understand the optimization.
 139.                                         */
 140.

 141.                                         //bytes in file are in Blue, Green, Red order
 142.                                         //int is 32 bits (8 bytes). So, we store the first two bytes of the pixel
 143.                                         // (which contain the Red value), and
 144.                                         //then shift everything over 1 byte (8bits) to make room for
 145.                                         //the green and blue values (remember the file is little endian), which we
 146.                                         // then write into the int in the right position
 147.                                         //The final value has the colors in the correct order (Red, Green, Blue)
 148.

 149.                                         var pixelValue:uint = fs.readUnsignedByte() | fs.readUnsignedShort() << 8;
 150.                                         pixels[position] = pixelValue;
 151.                                 }
 152.

 153.                                 //we are at the end of the row, so now we have to move the cursor
 154.                                 //forward so it ends on a multiple of 4
 155.                                 if(padding)
 156.                                 {
 157.                                         fs.position += padding;
 158.                                 }
 159.                         }
 160.

 161.                         //done reading file, close stream.
 162.                         fs.close();
 163.

 164.                         //create a Rectangle with width / height of Bitmap
 165.                         var rect:Rectangle = new Rectangle(0, 0, bmpWidth, bmpHeight);
 166.

 167.                         //create the BitmapData object to hold hold the BMP data.
 168.                         //we do a red fill here so it is easier to see if we have any errors
 169.                         //in our code
 170.                         var bmpData:BitmapData = new BitmapData(bmpWidth, bmpHeight, false, 0xFF0000);
 171.

 172.                         //copy the BMP pixel data into the BitmapData
 173.                         bmpData.setVector(rect, pixels);
 174.

 175.                         //create a new Bitmap instance using the BitmapData
 176.                         var bitmap:Bitmap = new Bitmap(bmpData);
 177.                         bitmap.x = 10;
 178.                         bitmap.y = 10;
 179.

 180.                         //add Bitmap to the display list
 181.                         addChild(bitmap);
 182.                 }
 183.         }
 184. }

复制代码
您可以从这里下载的例子。
感谢Lee的介绍,和Thibault Imbert帮助我了解endianes的一些细节,以及一些优化建议。
如果你有兴趣学习更多的知识,强烈建议你看看Lee的 FITC Presentation.

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片