您的位置:首页 > 编程语言 > C#

BMP图形文件分析类(c#)

2007-03-22 22:14 309 查看
1

using System;
2

using JJBase.FILE;
3

namespace JJBase.Image
4





{
5



/**//// <summary>
6

/// BMP 的摘要说明。
7

/// </summary>
8

public class BMP
9





{
10


11

public BMP()
12





{
13

//
14

//TODO: 在此处添加构造函数逻辑
15

//作者:梁俊杰
16

//时间:2005-9-29
17

//功能:分析bmp文件格式
18

//本文参考了林福宗老师的有关BMP文件格式的文章
19

//参考链接:http://www.chinahacker.net/article/showarticle.asp?articleid=20809
20

//参考链接:http://www.moon-soft.com/program/FORMAT/graphics/Bmp.html
21

//
22

}
23



/**//*BMP(BitMap-File)图形文件是Windows采用的图形文件格式,在Windows环境
24

* 下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各
25

* 图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与
26

* 显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB
27

* (device-dependent BitMap)文件格式。Windows 3.0以后的BMP图象文件与
28

* 显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB
29

* (device-independent BitMap)格式(注:Windows 3.0以后,在系统中仍
30

* 然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将
31

* 图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的
32

* 是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件
33

* 默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。
34

* */
35

public struct StructBMP
36





{
37

public BMPHeader Header;
38

public BMPPalette Palette;
39

public BMPData Data;
40

}
41

public struct BMPHeader
42





{
43



/**//*位图文件可看成由4个部分组成:位图文件头(BitMap-file header)、
44

* 位图信息头(BitMap-information header)、彩色表(color table)和
45

* 定义位图的字节阵列,
46

* */
47



public string Identifier;/**//*2 bytes,识别位图的类型:
48

‘BM’ : Windows 3.1x, 95, NT, …
49

‘BA’ :OS/2 BitMap Array
50

‘CI’ :OS/2 Color Icon
51

‘CP’ :OS/2 Color Pointer
52

‘IC’ : OS/2 Icon
53

‘PT’ :OS/2 Pointer
54

注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行。
55

*/
56

public System.Int32 FileSize;//1 dword,用字节表示的整个文件的大小
57

public byte[] Reserved;//1 dword,保留,必须设置为0
58

public System.Int32 BitMapDataOffset;//1 dword,从文件开始到位图数据开始之间的数据(BitMap data)之间的偏移量
59



public System.Int32 BitMapHeaderSize;/**//*1 dword
60

位图信息头(BitMap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:
61

28h - windows 3.1x, 95, nt, …
62

0ch - os/2 1.x
63

f0h - os/2 2.x
64

注:在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。
65

*/
66

public System.Int32 Width;//1 dword,位图的宽度,以象素为单位
67

public System.Int32 Height;//1 dword,位图的高度,以象素为单位
68

public System.Int16 Planes;//1 word,位图的位面数(注:该值将总是1)
69

public System.Int16 BitsPerPixel;
70



/**//*1 word
71

每个象素的位数
72

1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色)
73

4 - 16 色位图
74

8 - 256 色位图
75

16 - 16bit 高彩色位图
76

24 - 24bit 真彩色位图
77

32 - 32bit 增强型真彩色位图
78

*/
79

public System.Int32 Compression;
80



/**//*1 dword
81

压缩说明:
82

0 - 不压缩 (使用BI_RGB表示)
83

1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示)
84

2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示)
85

3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)
86

*/
87

public System.Int32 BitMapDataSize;//1 dword,用字节数表示的位图数据的大小。该数必须是4的倍数
88

public System.Int32 HResolution;//1 dword,用象素/米表示的水平分辨率
89

public System.Int32 VResolution;//1 dword,用象素/米表示的垂直分辨率
90

public System.Int32 Colors;//1 dword,位图使用的颜色数。如8-比特/象素表示为100h或者 256.
91

public System.Int32 ImportantColors;
92



/**//*1 dword,指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
93

*/
94

}
95

public struct BMPPalette
96





{
97

public byte[] Palette;//new byte[8192];//bmp规范没有规定调色板最大81926字节,此处可以根据程序需要调节
98



/**//*调色板数据根据BMP版本的不同而不同PaletteN * 4 byte调色板规范。
99

对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值: 1字节用于蓝色分量
100

1字节用于绿色分量
101

1字节用于红色分量
102

1字节用于填充符(设置为0)
103

*/
104

}
105

public struct BMPData
106





{
107

public byte[] BitMapData;//=new byte[1024000];//bmp规范没有规定bmp数据最多为1024000,此处可以根据需要调整
108



/**//*
109

图象数据根据BMP版本及调色板尺寸的不同而不同BitMap Dataxxx bytes该域的大小取决
110

于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是
111

彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。
112

*/
113

}
114

public void ProcessBMP(ref StructBMP sbmp,byte[] bytesFile)
115





{
116

byte[] word1=new byte[2];
117

byte[] word2=new byte[4];
118

System.Int32 result;
119

string str="";
120

word1[0]=bytesFile[0];
121

word1[1]=bytesFile[1];
122

str=FromBytesToString(word1);
123

sbmp.Header.Identifier=str;
124

word2[0]=bytesFile[2];
125

word2[1]=bytesFile[3];
126

word2[2]=bytesFile[4];
127

word2[3]=bytesFile[5];
128

result=this.FromBytesToInt32(word2);
129

sbmp.Header.FileSize=result;
130

word2[0]=bytesFile[10];
131

word2[1]=bytesFile[11];
132

word2[2]=bytesFile[12];
133

word2[3]=bytesFile[13];
134

result=this.FromBytesToInt32(word2);
135

sbmp.Header.BitMapDataOffset=result;
136

word2[0]=bytesFile[14];
137

word2[1]=bytesFile[15];
138

word2[2]=bytesFile[16];
139

word2[3]=bytesFile[17];
140

result=this.FromBytesToInt32(word2);
141

sbmp.Header.BitMapHeaderSize=result;
142

word2[0]=bytesFile[18];
143

word2[1]=bytesFile[19];
144

word2[2]=bytesFile[20];
145

word2[3]=bytesFile[21];
146

sbmp.Header.Width=result;
147

word2[0]=bytesFile[22];
148

word2[1]=bytesFile[23];
149

word2[2]=bytesFile[24];
150

word2[3]=bytesFile[25];
151

result=this.FromBytesToInt32(word2);
152

sbmp.Header.Height =result;
153

word1[0]=bytesFile[26];
154

word1[1]=bytesFile[27];
155

sbmp.Header.Planes=(System.Int16)FromBytesToInt32(word1);
156

word1[0]=bytesFile[28];
157

word1[1]=bytesFile[29];
158

sbmp.Header.BitsPerPixel=(System.Int16)FromBytesToInt32(word1);
159

word2[0]=bytesFile[30];
160

word2[1]=bytesFile[31];
161

word2[2]=bytesFile[32];
162

word2[3]=bytesFile[33];
163

result=this.FromBytesToInt32(word2);
164

sbmp.Header.Compression =result;
165

word2[0]=bytesFile[34];
166

word2[1]=bytesFile[35];
167

word2[2]=bytesFile[36];
168

word2[3]=bytesFile[37];
169

result=this.FromBytesToInt32(word2);
170

sbmp.Header.BitMapDataSize =result;
171

word2[0]=bytesFile[38];
172

word2[1]=bytesFile[39];
173

word2[2]=bytesFile[40];
174

word2[3]=bytesFile[41];
175

result=this.FromBytesToInt32(word2);
176

sbmp.Header.HResolution =result;
177

word2[0]=bytesFile[42];
178

word2[1]=bytesFile[43];
179

word2[2]=bytesFile[44];
180

word2[3]=bytesFile[45];
181

result=this.FromBytesToInt32(word2);
182

sbmp.Header.VResolution =result;
183

word2[0]=bytesFile[46];
184

word2[1]=bytesFile[47];
185

word2[2]=bytesFile[48];
186

word2[3]=bytesFile[49];
187

result=this.FromBytesToInt32(word2);
188

sbmp.Header.Colors =result;
189

word2[0]=bytesFile[50];
190

word2[1]=bytesFile[51];
191

word2[2]=bytesFile[52];
192

word2[3]=bytesFile[53];
193

result=this.FromBytesToInt32(word2);
194

sbmp.Header.ImportantColors =result;
195

//计算位图数据的开始位置
196

//sbmp.Header.BitMapDataSize是位图数据的大小,sbmp.Header.FileSize是整个文件的大小
197

//sbmp.Header.FileSize-sbmp.Header.BitMapDataSize-1就是位图数据的开始位置
198

//0x36到sbmp.Header.FileSize-sbmp.Header.BitMapDataSize-2就是调色板数据
199

result=sbmp.Header.FileSize-sbmp.Header.BitMapDataSize;
200

int j=0;
201

byte[] b=new byte[sbmp.Header.BitMapDataSize];
202

for(int i=result;i<sbmp.Header.FileSize;i++)
203





{
204

b[j]=bytesFile[i];j++;
205

}
206

sbmp.Data.BitMapData=b;
207

j=0;
208

b=new byte[result-sbmp.Header.BitMapDataOffset];
209

for(int i=sbmp.Header.BitMapDataOffset;i<result;i++)
210





{
211

b[j]=bytesFile[i];j++;
212

}
213

sbmp.Palette.Palette=b;
214

}
215

public void ProcessBMP(ref StructBMP sbmp,string File)
216





{
217

//先读取文件成字节数组,统一由ProcessBMP(StructBMP sbmp,byte[] bytesFile)处理
218

JJBase.FILE.ReadAndWrite f=new ReadAndWrite();
219

byte[] result=f.ReadBytesFromFile(File);
220

ProcessBMP(ref sbmp,result);
221

}
222

private System.Int32 FromBytesToInt32(byte[] b)
223





{
224

System.Int32 result=0;
225

System.Int32 t=0;
226

for(int i=b.Length-1;i>=0;i--)
227





{
228


229

if((int)b[i]!=0)
230





{
231

t=(int)Math.Pow(256,i);
232

result+=(int)b[i]*t;
233

}
234


235

}
236

return result;
237

}
238

private string FromBytesToString(byte[] b)
239





{
240

string result="";
241

for(int i=0;i<b.Length;i++)
242





{
243

result+=Convert.ToChar((int)(b[i])).ToString();
244

}
245

return result;
246

}
247


248

}
249

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: