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
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249
