/**
* *-----------------------------*
* | *** BMP格式解析类 *** |
* *-----------------------------*
*
* 编辑修改收录:fengzi(疯子、wu341、wgq341)
*
* 不会写代码,我是代码搬运工。
*
* 联系方式:QQ(493712833)。
*
* 随 笔: https://www.cnblogs.com/fengziwu/
*
* 版权协议:请自觉遵守LGPL协议,欢迎修改、复制、转载、传播给更多需要的人。
* 免责声明:任何因使用此软件导致的纠纷与软件/程序开发者无关。
* 日 期: 2019.05.08
*
* ---------------------- 实例 --------------------------- *
var req : URLRequest;
var loa : URLLoader; // 二进制加载BMP文件
load( "4位压缩.bmp" ); // 二进制加载BMP文件
function load ( url:String ) : void{
req = new URLRequest( url );
loa = new URLLoader();
loa.dataFormat = URLLoaderDataFormat.BINARY;
loa.addEventListener( Event.COMPLETE, loaComplete );
loa.load( req );
} // 加载BMP完成
function loaComplete ( eve:Event ) : void
{
loa.removeEventListener( Event.COMPLETE, loaComplete ); // 解析BMP文件
analysisDisplay();
} //***** BMP解析以及显示 ***
// BMP格式解析对象
var bmpAna : BMPAnalytical; // 舞台上的Bitmap对象数组,用于显示位图
var bitmap : Bitmap; // 解析显示BMP文件
function analysisDisplay () : void
{
bmpAna = new BMPAnalytical();
bmpAna.analyticalByteArray( loa.data );
bitmap = new Bitmap( bmpAna.ImageDate );
bitmap.x = 100;
bitmap.y = 100;
addChild( bitmap );
}
*/ package fengzi.bmd
{
import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.display.BitmapData; /**
* BMPAnalytical BMP格式解析类,用于解析BMP格式二进制数据,并且从中获取位图数据信息。
*/
public class BMPAnalytical
{
private var mydata : ByteArray; //BMP图像数据的地址
private var bfOffBits : uint; //BMP图像的宽度,单位像素
private var biWidth : uint; //BMP图像的高度,单位像素
private var biHeight : uint; //平面数
private var biPlanes : uint; //BMP图像的色深,即一个像素用多少位表示,常见有1、4、8、16、24和32,分别对应单色、16色、256色、16位高彩色、24位真彩色和32位增强型真彩色
private var biBitCount : uint; //压缩方式,0表示不压缩,1表示RLE8压缩,2表示RLE4压缩,3表示每个像素值由指定的掩码决定
private var biCompression : uint; //BMP图像数据大小,必须是4的倍数,图像数据大小不是4的倍数时用0填充补足
private var biSizeImage : uint; //水平分辨率
private var biXPelsPerMeter : uint; //垂直分辨率
private var biYPelsPerMeter : uint; //BMP图像使用的颜色,0表示使用全部颜色,对于256色位图来说,此值为100h = 256
private var biClrUsed : uint; //重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色
private var biClrImportant : uint; //调色盘
private var colorArray : Vector.<uint>; //位图数据
private var imagedata : BitmapData; /**
* 构造函数
*/
public function BMPAnalytical ()
{ } /**
* 解析由[Embed()]元素直接获取的图片对象,例如:[Embed(source="4位压缩.bmp",mimeType="application/octet-stream")]
*/
public function analyticalClass ( bmpClass:Class ) : void
{
// constructor code
this.mydata = new bmpClass as ByteArray;
this.mydata.endian = Endian.LITTLE_ENDIAN;
BITMAPFILEHEADER();
BITMAPINFOHEADER();
colortable();
bitmapdata();
}
/**
* 解析由URLLoader等方法二进制加载图片对象
*/
public function analyticalByteArray ( bmpByteArray:ByteArray ) : void
{
this.mydata = bmpByteArray;
this.mydata.endian = Endian.LITTLE_ENDIAN;
BITMAPFILEHEADER();
BITMAPINFOHEADER();
colortable();
bitmapdata();
} private function BITMAPFILEHEADER () : void
{
if ( this.mydata.readUTFBytes(2) != "BM" )
{
throw new Error( "不是BMP文件!" )
}
if ( this.mydata.readUnsignedInt() != this.mydata.length )
{
throw new Error( "文件不全!" );
}
this.mydata.position += 4;
this.bfOffBits = this.mydata.readUnsignedInt();
//trace( "BMP图像数据的地址:" + this.bfOffBits );
} //位图文件头
private function BITMAPINFOHEADER () : void
{
this.mydata.position += 4;
this.biWidth = this.mydata.readUnsignedInt();
//trace( "BMP图像的宽度:" + this.biWidth ) this.biHeight = this.mydata.readUnsignedInt();
//trace( "BMP图像的高度:" + this.biHeight ) this.biPlanes = this.mydata.readUnsignedShort();
this.biBitCount = this.mydata.readUnsignedShort();
//trace( "BMP图像的色深:" + this.biBitCount ); this.biCompression = this.mydata.readUnsignedInt();
//trace( "压缩方式:" + this.biCompression ); this.biSizeImage = this.mydata.readUnsignedInt();
//trace( "BMP图像数据大小:" + this.biSizeImage ); this.biXPelsPerMeter = this.mydata.readUnsignedInt();
this.biYPelsPerMeter = this.mydata.readUnsignedInt();
this.biClrUsed = this.mydata.readUnsignedInt();
this.biClrImportant = this.mydata.readUnsignedInt();
} //位图信息头
private function colortable () : void
{
if ( this.biBitCount <= 8 )
{
this.colorArray = new Vector.<uint>();
//trace( "使用调色盘!" )
var r:uint,g:uint,b:uint,color:uint,i:uint; var end : uint = Math.pow( 2, this.biBitCount );
for ( i = 0; i < end; i++ )
{
b = this.mydata.readUnsignedByte();
g = this.mydata.readUnsignedByte();
r = this.mydata.readUnsignedByte();
this.mydata.position++;
color = (r<<16) + (g<<8) + b;
this.colorArray[i] = color;
}
}
else
{
//trace("不使用调色盘!")
}
} //彩色表/调色板
private function bitmapdata () : void
{
this.mydata.position = this.bfOffBits;
var Offset : uint;//每行偏移 var i:uint,j:uint,p:uint,color:uint,r:uint,g:uint,b:uint,a:uint; var end:uint,bytes1:uint,bytes2:uint,k:uint,x:uint,y:uint; if ( this.biBitCount <= 8 )
{
this.imagedata = new BitmapData( this.biWidth, this.biHeight, false, 0x000000 );
if ( this.biBitCount == 8 )
{
if ( this.biCompression == 0 )
{
Offset = this.biSizeImage / this.biHeight - this.biWidth;//每行偏移
for ( i = 0; i < this.biHeight; i++ )
{
for ( j = 0; j < this.biWidth; j++ )
{
p = this.mydata.readUnsignedByte();
color = this.colorArray[p];
this.imagedata.setPixel( j, this.biHeight - i - 1, color );
if ( j == this.biWidth - 1 )
{
this.mydata.position += Offset;
}
}
}
//不压缩
}
else
{
x = 0;
y = 0;
while ( this.mydata.bytesAvailable > 0 )
{
bytes1 = this.mydata.readUnsignedByte();
bytes2 = this.mydata.readUnsignedByte();
if ( bytes1 >= 0x01 )
{
for ( i = 0; i < bytes1; i++ )
{
color = this.colorArray[bytes2];
this.imagedata.setPixel( x, this.biHeight - y - 1, color );
x++;
}
//每像素8位的BMP文件,连续重复数据以两字节表示,第一个字节记录重复次数,第二字节记录重复数据。
}
else
{
if ( bytes2 >= 0x03 )
{
for ( i = 0; i < bytes2; i++ )
{
p = this.mydata.readUnsignedByte();
color = this.colorArray[p];
this.imagedata.setPixel( x, this.biHeight - y - 1, color );
x++;
}
if ( this.mydata.readUnsignedByte() == 0x00 )
{
//无重复像素结束符
}
else
{
this.mydata.position--;
}
}
//如果是3个以上不重复的数据字节,第1个字节为00,第2个字节记录该不重复的数据串的长度(以字节为单位)
else if ( bytes2 == 0x02 )
{
x += this.mydata.readUnsignedByte();
y += this.mydata.readUnsignedByte();
}
//像素位置跳转符
else if ( bytes2 == 0x01 )
{
//图像结束符
break;
}
else
{
x = 0;
y++;
//换行符
}
}
}
//压缩
}
}
//8位图像
var bit:uint,str:String,Num:uint;
var p1:uint,p2:uint,p3:uint,p4:uint,p5:uint,p6:uint,p7:uint,p8:uint; if ( this.biBitCount == 1 )
{
Offset = this.biSizeImage / this.biHeight;//每行偏移
for ( i = 0; i < this.biHeight; i++ )
{
for ( j = 0; j < Offset; j++ )
{
bit = this.mydata.readUnsignedByte() + 256;
str = bit.toString(2);
p1 = uint( str.charAt(1) );
p2 = uint( str.charAt(2) );
p3 = uint( str.charAt(3) );
p4 = uint( str.charAt(4) );
p5 = uint( str.charAt(5) );
p6 = uint( str.charAt(6) );
p7 = uint( str.charAt(7) );
p8 = uint( str.charAt(8) );
this.imagedata.setPixel( j*8,this.biHeight-i-1,this.colorArray[p1] );
this.imagedata.setPixel( j*8+1,this.biHeight-i-1,this.colorArray[p2] );
this.imagedata.setPixel( j*8+2,this.biHeight-i-1,this.colorArray[p3] );
this.imagedata.setPixel( j*8+3,this.biHeight-i-1,this.colorArray[p4] );
this.imagedata.setPixel( j*8+4,this.biHeight-i-1,this.colorArray[p5] );
this.imagedata.setPixel( j*8+5,this.biHeight-i-1,this.colorArray[p6] );
this.imagedata.setPixel( j*8+6,this.biHeight-i-1,this.colorArray[p7] );
this.imagedata.setPixel( j*8+7,this.biHeight-i-1,this.colorArray[p8] );
}
}
}
//1位图像
if ( this.biBitCount == 4 )
{
if ( this.biCompression == 0 )
{
Offset = this.biSizeImage/this.biHeight;//每行偏移
for ( i = 0; i < this.biHeight; i++ )
{
for ( j = 0; j < Offset; j++ )
{
bit = this.mydata.readUnsignedByte();
p2 = bit>>4;
p1 = bit-(p2<<4);
this.imagedata.setPixel(j*2,this.biHeight-i-1,this.colorArray[p2]);
this.imagedata.setPixel(j*2+1,this.biHeight-i-1,this.colorArray[p1]);
}
}
//不压缩
}
else
{
x = 0;
y = 0;
var col1:uint,col2:uint,b1:uint;
while ( this.mydata.bytesAvailable > 0 )
{
bytes1 = this.mydata.readUnsignedByte();
bytes2 = this.mydata.readUnsignedByte();
if ( bytes1 >= 0x01 )
{
col2 = bytes2>>4;
col1 = bytes2-(col2<<4);
for ( i = 0; i < bytes1; i++ )
{
if ( i%2 == 0 )
{
p = col2;
}
else
{
p = col1;
}
color = this.colorArray[p];
this.imagedata.setPixel( x, this.biHeight-y-1, color );
x++;
}
//重复的像素值
}
else
{
if ( bytes2 >= 0x03 )
{
for ( i = 0; i < bytes2; i++ )
{
if ( i%2 == 0 )
{
b1 = this.mydata.readUnsignedByte();
col2 = b1>>4;
col1 = b1-(col2<<4);
p = col2;
}
else
{
p = col1;
}
color = this.colorArray[p];
this.imagedata.setPixel(x,this.biHeight-y-1,color);
x++;
}
if ( this.mydata.readUnsignedByte() == 0x00 )
{
//无重复像素结束符
}
else
{
this.mydata.position--;
}
//如果是3个以上不重复的数据字节,第1个字节为00,第2个字节记录该不重复的数据串的长度(以字节为单位)
//不重复的像素值
}
else if ( bytes2 == 0x02 )
{
x += this.mydata.readUnsignedByte();
y += this.mydata.readUnsignedByte();
//像素位置跳转符
}
else if ( bytes2 == 0x01 )
{
break;
//图像结束符
}
else
{
x = 0;
y++;
//换行符
}
}
}
//压缩
}
}//4位图像
//使用调色盘
}
else
{
if ( this.biBitCount == 32 )
{
this.imagedata = new BitmapData(this.biWidth,this.biHeight,true,0xff000000);
Offset = (this.biSizeImage-this.biWidth*this.biHeight*4)/this.biHeight;
for ( i = 0; i < this.biHeight; i++ )
{
for ( j = 0; j < this.biWidth; j++ )
{
b = this.mydata.readUnsignedByte();
g = this.mydata.readUnsignedByte();
r = this.mydata.readUnsignedByte();
a = this.mydata.readUnsignedByte();
color = (a<<24)+(r<<16)+(g<<8)+b;
this.imagedata.setPixel(j,this.biHeight-i-1,color);
if ( j == this.biWidth-1 )
{
this.mydata.position += Offset;
}
}
}
//有透明度的位图
}
else
{
this.imagedata = new BitmapData(this.biWidth,this.biHeight,false,0x000000);
if ( this.biBitCount == 24 )
{
Offset = (this.biSizeImage-this.biWidth*this.biHeight*3)/this.biHeight;
for ( i = 0; i < this.biHeight; i++ )
{
for ( j = 0; j < this.biWidth; j++ )
{
b = this.mydata.readUnsignedByte();
g = this.mydata.readUnsignedByte();
r = this.mydata.readUnsignedByte();
color = (r<<16)+(g<<8)+b;
this.imagedata.setPixel(j,this.biHeight-i-1,color);
if ( j == this.biWidth-1 )
{
this.mydata.position += Offset;
}
}
}
}//24位图像
var shortint:uint;
if ( this.biBitCount == 16 )
{
Offset = (this.biSizeImage-this.biWidth*this.biHeight*2)/this.biHeight;
if ( this.biCompression == 3 )
{
for ( i = 0; i < this.biHeight; i++ )
{
for ( j = 0; j < this.biWidth; j++ )
{
shortint = this.mydata.readUnsignedShort();
r = shortint>>11;
g = (shortint-(b<<11))>>5;
b = shortint-(b<<11)-(g<<5);
color = (r<<19)+(g<<10)+(b<<3);
this.imagedata.setPixel(j,this.biHeight-i-1,color);
if ( j == this.biWidth-1 )
{
this.mydata.position += Offset;
}
}
}
}//565压缩
if ( this.biCompression == 0 )
{
for ( i = 0; i < this.biHeight; i++ )
{
for ( j = 0; j < this.biWidth; j++ )
{
shortint = this.mydata.readUnsignedShort();
shortint = shortint-((shortint>>15)<<15);
r = shortint>>10;
g = (shortint-(b<<10))>>5;
b = shortint-(b<<10)-(g<<5);
color = (r<<19)+(g<<11)+(b<<3);
this.imagedata.setPixel(j,this.biHeight-i-1,color);
if ( j == this.biWidth-1 )
{
this.mydata.position += Offset;
}
}
}
}//X555压缩
}//16位图像
//没有透明度的位图
}
//不使用调色盘
}
}//位图数据
public function get ImageDate() : BitmapData
{
return this.imagedata;
}//返回位图数据
}
}

  

AS3.0 位图(BMP)解析类的更多相关文章

  1. AS3.0 自定义右键菜单类

    AS3.0 自定义右键菜单类: /** * 自定义右键菜单类 * 自定义菜单项不得超过15个,每个标题必须至少包含一个可见字符. * 标题字符不能超过100个,并且开头的空白字符会被忽略. * 与任何 ...

  2. AS3.0 位图翻转、旋转

    /* * * *-------------------------* * | *** 位图翻转.旋转 *** | * *-------------------------* * * 作 者:fengz ...

  3. As3.0 Interface 与类的使用

    来源:http://blog.sina.com.cn/s/blog_4d65c19e0100bfkb.html 抽象类:又叫抽象基类:可以包含一般类所包含的所有特性,例如,字段,属性,方法,抽象类不能 ...

  4. As3.0 类的【枚举】

    As3.0 类的枚举   “枚举”是您创建的一些自定义数据类型,用于封装一小组值.ActionScript 3.0 并不支持具体的枚举工具,这与 C++ 使用 enum 关键字或 Java 使用 En ...

  5. “AS3.0高级动画编程”学习:第一章高级碰撞检测

    AdvancED ActionScript 3.0 Animation 是Keith Peters大师继"Make Things Move"之后的又一力作,网上已经有中文翻译版本了 ...

  6. solr&lucene3.6.0源码解析(四)

    本文要描述的是solr的查询插件,该查询插件目的用于生成Lucene的查询Query,类似于查询条件表达式,与solr查询插件相关UML类图如下: 如果我们强行将上面的类图纳入某种设计模式语言的话,本 ...

  7. solr&lucene3.6.0源码解析(三)

    solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下 从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用 UpdateRequestProcessor相当于责任链模式 ...

  8. HTML解析类 ,让你不使用正则也能轻松获取HTML相关元素 -C# .NET

    功能: 1.轻松获取指元素HTML元素. 2.可以根据属性标签进行筛选 3.返回的都是Llist强类型无需转换 用过XElement的都知道 用来解析XML非常的方便,但是对于HTML的格式多样化实在 ...

  9. Heritrix 3.1.0 源码解析(三十七)

    今天有兴趣重新看了一下heritrix3.1.0系统里面的线程池源码,heritrix系统没有采用java的cocurrency包里面的并发框架,而是采用了线程组ThreadGroup类来实现线程池的 ...

随机推荐

  1. [转]MATLAB 2018b 中文版下载与安装教程

    MATLAB R2018b_win64.iso 压缩包一个 MATLAB R2018b Win64 Crack 压缩包一个 一.下载与安装   1 下载中文原程序安装包和破解文件,链接: https: ...

  2. colormap是MATLAB里面用来设定和获取当前色图的函数。

    下面将举例.描述MATLAB内建的色图.用户除了可以编程指定MATLAB内建的色图,还可以使用Plot Tools图形用具界面的Figure Properties面板中的Colormap菜单来选择一种 ...

  3. Tosca : 把 inner text 放到变量里,定义变量,使用变量

    XB的是分开取 注意颜色要变成蓝色的,才可用 上面是定义 下面是使用 键盘输入变量

  4. yii2增删改查操作

    https://www.yiichina.com/tutorial/996 https://www.yiichina.com/tutorial/834 一.新增 使用model::save()操作进行 ...

  5. 泡泡一分钟:Perception-aware Receding Horizon Navigation for MAVs

    作为在空中抛掷四旋翼飞行器后恢复的第一步,它需要检测它使用其加速度计的发射.理想的情况下,在飞行中,加速度计理想地仅测量由于施加的转子推力引起的加速度,即.因此,当四旋翼飞行器发射时,我们可以检测到测 ...

  6. 使用Scanner

    在上个步骤中,每次要发不同的数据都需要修改代码 可以使用Scanner读取控制台的输入,并发送到服务端,这样每次都可以发送不同的数据了.   1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  7. 转 Zabbix 3.2.6通过SNMP和iDRAC监控DELL服务器

    https://www.cnblogs.com/saneri/p/7772641.html

  8. 【435】NULL '\0' 0 等在 C 语言中的区别

    参考:C/C++语言中NULL.'\0’和0的区别 参考:空字符串.'\0'.0与NULL的区别以及数组清零的特点分析 在 C语言 中没有 空字符 这个东西 '',不过有 空字符串 "&qu ...

  9. redis 部署

    wget http://download.redis.io/releases/redis-4.0.14.tar.gz tar -zxvf redis-4.0.14.tar.gz mv redis-4. ...

  10. composer 添加贝宝PayPal

    composer require "paypal/rest-api-sdk-php:1.7.2"