经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
c语言数字图像处理(一):bmp图片格式及灰度图片转换
来源:cnblogs  作者:GoleBeetle  时间:2018/9/25 19:30:44  对本文有异议

本篇文章首先介绍了bmp图片格式,主要参考wiki上的内容,包括bmp文件的存储方式,对于一些常见的bmp文件格式都给了例子,并且对8位 16位RGB555 16位RGB565格式的bmp文件进行了简单分析,最后的代码可以将8位,16位,24位,32位色彩深度的bmp文件转化位8位灰度图片,用作后续文章中算法的测试图片。

Bmp file structure

Bitmap file header

DIB header (bitmap information header)

compression method

 

色彩深度  1bpp = 1位色彩深度,存储一个像素点使用1位,可以表示两种颜色

bpp <= 8 必须有调色板(color table)

bpp = 1 调色板 2 * 4 字节

bpp = 4 调色板 16 * 4 字节

bpp = 8 调色板 256 * 4 字节

In most cases, each entry in the color table occupies 4 bytes, in the order blue, green, red, 0x00 (see below for exceptions).The color table is a block of bytes (a table) listing the colors used by the image. Each pixel in an indexed color image is described by a number of bits (1, 4, or 8) which is an index of a single color described by this table. The purpose of the color palette in indexed color bitmaps is to inform the application about the actual color that each of these index values corresponds to. The purpose of the color table in non-indexed (non-palettized) bitmaps is to list the colors used by the bitmap for the purposes of optimization on devices with limited color display capability and to facilitate future conversion to different pixel formats and paletization.

<https://en.wikipedia.org/wiki/BMP_file_format>

调色板数据格式 [blue][green][red][alpha = 0x00]

 

 位图格式分析

1bpp(单色位图)        

 

4bpp(16色位图)

 

8bpp(256色位图)

bmp头文件和DIB头

 

0x00000436                  位图数据偏移1078字节 调色板1078 - 54 = 1024字节 调色板为256个数据的数组,每个数组4字节

54字节之后的内容为调色板,1078字节之后的内容为位图数据

调色板数据为这副图片中用到的所有颜色数据,位图数据块的内容为调色板数据的索引

 

16bpp(RGB555 无压缩compression = BI_RGB,无调色板,无掩码bitmask)

二进制文件为

Bmp头文件

0x424d                      bmp文件开头

0x004b0038                  bmp文件大小 为4915256字节

四个字节保留位

0x00000036                  位图数据地址偏移   54字节

 

DIB头

0x00000028                  DIB头大小  40字节

0x00000780                  宽度1920像素

0x00000500                  高度1280像素(有符号整数,若<0,解析图片时上下翻转)

0x0001                      调色板的数量1

0x0010                      每个像素点的位数 16位

0x00000000                  压缩方式,无压缩

0x004b0002                  像素数据大小 4915202 = 4915256 - 54

0x00000b12                  横向分辨率每米2834像素

0x00000b12                  纵向分辨率

0x00000000                  调色板颜色数

0x00000000                  重要颜色数

其余为位图数据

 

16bpp(RGB565 压缩方式BI_BITFIELDS 无调色板 有附加掩码位bitmask)

 

0x00000042                         位图数据偏移66字节  存在66 - 54 = 12字节的附加掩码位

0x00000003                         压缩方式BI_BITFIELDS

0x0000f800[R]                      附加掩码位,读取一个像素之后,可以分别用掩码“与”上像素值,

0x000007e0[G]                      从而提取出想要的颜色分量

0x0000001f[B]                      例如 像素值 & 0xf800  为红色分量的值

66字节以后为位图数据

 

将bmp文件转换为8位灰度图片 

  1. 1 #include <stdio.h>
  2. 2 #include <stdlib.h>
  3. 3 #include <string.h>
  4. 4 #include <math.h>
  5. 5
  6. 6 #define GRAY_LEVELS 255
  7. 7
  8. 8 struct bmpfileheader{
  9. 9 unsigned short filetype;
  10. 10 unsigned long filesize;
  11. 11 short reserved1;
  12. 12 short reserved2;
  13. 13 unsigned long bitmapoffset;
  14. 14 };
  15. 15
  16. 16 struct bitmapheader{
  17. 17 unsigned long size;
  18. 18 long width;
  19. 19 long height;
  20. 20 unsigned short planes;
  21. 21 unsigned short bitsperpixel;
  22. 22 unsigned long compression;
  23. 23 unsigned long sizeofbitmap;
  24. 24 unsigned long horzres;
  25. 25 unsigned long vertres;
  26. 26 unsigned long colorsused;
  27. 27 unsigned long colorsimp;
  28. 28 };
  29. 29
  30. 30 struct ctstruct{
  31. 31 unsigned char blue;
  32. 32 unsigned char green;
  33. 33 unsigned char red;
  34. 34 };
  35. 35
  36. 36 union colortable_union{
  37. 37 struct colortable
  38. 38 {
  39. 39 unsigned char blue;
  40. 40 unsigned char green;
  41. 41 unsigned char red;
  42. 42 unsigned char reserved;
  43. 43 }colortable;
  44. 44 unsigned long l_num;
  45. 45 };
  46. 46
  47. 47 union short_char_union{
  48. 48 short s_num;
  49. 49 char s_alpha[2];
  50. 50 };
  51. 51
  52. 52 union int_char_union{
  53. 53 int i_num;
  54. 54 char i_alpha[2];
  55. 55 };
  56. 56
  57. 57 union long_char_union{
  58. 58 long l_num;
  59. 59 char l_alpha[4];
  60. 60 };
  61. 61
  62. 62 union float_char_union{
  63. 63 float f_num;
  64. 64 char f_alpha[4];
  65. 65 };
  66. 66
  67. 67 union ushort_char_union{
  68. 68 short s_num;
  69. 69 char s_alpha[2];
  70. 70 };
  71. 71
  72. 72 union uint_char_union{
  73. 73 int i_num;
  74. 74 char i_alpha[2];
  75. 75 };
  76. 76
  77. 77 union ulong_char_union{
  78. 78 long l_num;
  79. 79 char l_alpha[4];
  80. 80 };
  81. 81
  82. 82 union rgb565_union{
  83. 83 struct rgb565_struct
  84. 84 {
  85. 85 unsigned red : 5;
  86. 86 unsigned green : 6;
  87. 87 unsigned blue : 5;
  88. 88 }rgb565_struct;
  89. 89 // short pixel;
  90. 90 char exchange[2];
  91. 91 };
  92. 92
  93. 93 union rgb555_union{
  94. 94 struct rgb555_struct
  95. 95 {
  96. 96 unsigned red : 5;
  97. 97 unsigned green : 5;
  98. 98 unsigned blue : 5;
  99. 99 unsigned reserved : 1;
  100. 100 }rgb555_struct;
  101. 101 // short pixel;
  102. 102 char exchange[2];
  103. 103 };
  104. 104
  105. 105 union bpp24_union{
  106. 106 struct bpp24_struct
  107. 107 {
  108. 108 unsigned red : 8;
  109. 109 unsigned green : 8;
  110. 110 unsigned blue : 8;
  111. 111 }bpp24_struct;
  112. 112 char exchange[3];
  113. 113 };
  114. 114
  115. 115 union bpp32_union{
  116. 116 struct bpp32_struct
  117. 117 {
  118. 118 unsigned red : 8;
  119. 119 unsigned green : 8;
  120. 120 unsigned blue : 8;
  121. 121 unsigned reserved : 8;
  122. 122 }bpp32_struct;
  123. 123 char exchange[4];
  124. 124 };
  125. 125
  126. 126 int get_image_size(const char* file_name, long* rows, long* cols);
  127. 127 void extract_long_from_buffer(char buffer[], int lsb, int start, long* number);
  128. 128 void extract_ulong_from_buffer(char buffer[], int lsb, int start,unsigned long* number);
  129. 129 void extract_short_from_buffer(char buffer[], int lsb, int start, short* number);
  130. 130 void extract_ushort_from_buffer(char buffer[], int lsb, int start, unsigned short* number);
  131. 131 void insert_short_into_buffer(char buffer[], int start, short number);
  132. 132 void insert_ushort_into_buffer(char buffer[], int start, unsigned short number);
  133. 133 void insert_long_into_buffer(char buffer[], int start, long number);
  134. 134 void insert_ulong_into_buffer(char buffer[], int start, unsigned long number);
  135. 135 short **allocate_image_array(long length, long width);
  136. 136 int free_image_array(short **the_array, long length);
  137. 137 void create_allocate_bmp_file(const char* file_name, struct bmpfileheader* file_header, struct bitmapheader* bmheader);
  138. 138 void read_bmp_file_header(const char* file_name, struct bmpfileheader* file_header);
  139. 139 void read_bm_header(const char* file_name, struct bitmapheader* bmheader);
  140. 140 int calculate_pad(long width);
  141. 141 void write_bmp_image(const char* file_name, short **array);
  142. 142 int does_not_exist(const char* file_name);
  143. 143 union colortable_union* read_allocate_colortable(const char* file_name, struct bitmapheader* bmheader);
  144. 144 void free_colortable(union colortable_union* colortable);
  145. 145 void bpp82grayscale(long height, long width, FILE* fp, short** the_image, int pad,
  146. 146 const char* file_name, struct bitmapheader* bmheader);
  147. 147 void rgb5552grayscale(long height, long width, FILE* fp, short** the_image, int pad);
  148. 148 void rgb5652grayscale(long height, long width, FILE* fp, short** the_image, int pad);
  149. 149 void bpp242grayscale(long height, long width, FILE* fp, short** the_image, int pad);
  150. 150 void bpp322grayscale(long height, long width, FILE* fp, short** the_image, int pad);
  151. 151 void rgb2grayscale_array(const char* file_name, short** the_image);
  152. 152 void flip_image_array(short** the_image, long rows, long cols);
  153. 157
  154. 158 int main(int argc, char const *argv[])
  155. 159 {
  156. 160 char* cc;
  157. 161 long l, w;
  158. 162 short** grayscale_array;
  159. 163 struct bmpfileheader bmp_file_header;
  160. 164 struct bitmapheader bmheader;
  161. 165
  162. 166 if(argc < 3){
  163. 167 printf("\nusage: rgb5652bmp rgb565-file-name grayscale-file-name\n");
  164. 168 exit(-1);
  165. 169 }
  166. 170 if(does_not_exist(argv[1])){
  167. 171 printf("\nERROR input file %s does not exist", argv[1]);
  168. 172 exit(0);
  169. 173 }
  170. 174 cc = strstr(argv[1], ".bmp");
  171. 175 if(cc == NULL){
  172. 176 printf("\nERROR %s must be a bmp file", argv[1]);
  173. 177 exit(0);
  174. 178 }
  175. 179 cc = strstr(argv[2], ".bmp");
  176. 180 if(cc == NULL){ /* create a bmp */
  177. 181 printf("\nERROR %s must be a bmp file name", argv[2]);
  178. 182 exit(0);
  179. 183 }
  180. 184
  181. 185 get_image_size(argv[1], &l, &w);
  182. 186 grayscale_array = allocate_image_array(l, w);
  183. 187 bmheader.height = l;
  184. 188 bmheader.width = w;
  185. 189
  186. 190 create_allocate_bmp_file(argv[2], &bmp_file_header, &bmheader); // create grayscale image file
  187. 191
  188. 192 rgb2grayscale_array(argv[1], grayscale_array);
  189. 193 write_bmp_image(argv[2], grayscale_array);
  190. 194
  191. 195 free_image_array(grayscale_array, l);
  192. 196
  193. 197 return 0;
  194. 198 }
  195. 199
  196. 200 void rgb2grayscale_array(const char* file_name, short** the_image)
  197. 201 {
  198. 202 FILE* fp;
  199. 203 int negative = 0,
  200. 204 pad = 0;
  201. 205 long height = 0,
  202. 206 width = 0;
  203. 207 struct bmpfileheader file_header;
  204. 208 struct bitmapheader bmheader;
  205. 211
  206. 212 read_bmp_file_header(file_name, &file_header);
  207. 213 read_bm_header(file_name, &bmheader);
  208. 214
  209. 215 fp = fopen(file_name, "rb");
  210. 216 fseek(fp, file_header.bitmapoffset, SEEK_SET);
  211. 217
  212. 218 width = bmheader.width;
  213. 219 if(bmheader.height < 0){
  214. 220 height = bmheader.height * (-1);
  215. 221 negative = 1;
  216. 222 }
  217. 223 else
  218. 224 height = bmheader.height;
  219. 225
  220. 226 pad = calculate_pad(width);
  221. 227
  222. 228 if (bmheader.bitsperpixel == 16 && bmheader.compression == 0x03)
  223. 229 rgb5652grayscale(height, width, fp, the_image, pad);
  224. 230 else if (bmheader.bitsperpixel == 16 && bmheader.compression == 0x00)
  225. 231 rgb5552grayscale(height, width, fp, the_image, pad);
  226. 232 else if (bmheader.bitsperpixel == 24 && bmheader.compression == 0x00)
  227. 233 bpp242grayscale(height, width, fp, the_image, pad);
  228. 234 else if (bmheader.bitsperpixel == 32 && bmheader.compression == 0x00)
  229. 235 bpp322grayscale(height, width, fp, the_image, pad);
  230. 236 else if (bmheader.bitsperpixel == 8)
  231. 237 bpp82grayscale(height, width, fp, the_image, pad, file_name, &bmheader);
  232. 238 else
  233. 239 {
  234. 240 printf("Unknow image format\n");
  235. 241 exit(0);
  236. 242 }
  237. 243
  238. 244 if(negative == 0)
  239. 245 flip_image_array(the_image, height, width);
  240. 246 }
  241. 247
  242. 248 void bpp82grayscale(long height, long width, FILE* fp, short** the_image, int pad,
  243. 249 const char* file_name, struct bitmapheader* bmheader)
  244. 250 {
  245. 251 union colortable_union* colortable = NULL;
  246. 252 unsigned char pixel_index;
  247. 253
  248. 254 colortable = read_allocate_colortable(file_name, bmheader);
  249. 255 for(int i=0; i<height; i++){
  250. 256 for(int j=0; j<width; j++){
  251. 257 fread(&pixel_index, 1, 1, fp);
  252. 258 // printf("%u\n", pixel_index);
  253. 259 the_image[i][j] = ((colortable[pixel_index].colortable.red) +
  254. 260 (colortable[pixel_index].colortable.blue) +
  255. 261 (colortable[pixel_index].colortable.green)) / 3;
  256. 262 } /* ends loop over j */
  257. 263 if(pad != 0){
  258. 264 fseek(fp, pad, SEEK_CUR);
  259. 265 } /* ends if pad 1= 0 */
  260. 266 } /* ends loop over i */
  261. 267 free_colortable(colortable);
  262. 268 }
  263. 269
  264. 270 union colortable_union* read_allocate_colortable(const char* file_name, struct bitmapheader* bmheader)
  265. 271 {
  266. 272 union colortable_union* colortable = NULL;
  267. 273 char buffer[10];
  268. 274 unsigned long ull;
  269. 275 FILE *fp;
  270. 276 long table_size = (long)pow(2, bmheader->bitsperpixel);
  271. 277
  272. 278 fp = fopen(file_name, "rb");
  273. 279 colortable = malloc(sizeof(union colortable_union) * table_size);
  274. 280
  275. 281 fseek(fp, 54, SEEK_SET);
  276. 282
  277. 283 for (int i = 0; i < table_size; i++)
  278. 284 {
  279. 285 fread(buffer, 1, 4, fp);
  280. 286 extract_ulong_from_buffer(buffer, 1, 1, &ull);
  281. 287 colortable[i].l_num = ull;
  282. 288 }
  283. 289
  284. 290 fclose(fp);
  285. 291 return colortable;
  286. 292 }
  287. 293
  288. 294 void free_colortable(union colortable_union* colortable)
  289. 295 {
  290. 296 free(colortable);
  291. 297 }
  292. 298
  293. 299 void rgb5652grayscale(long height, long width, FILE* fp, short** the_image, int pad)
  294. 300 {
  295. 301 union rgb565_union pixel;
  296. 302
  297. 303 for(int i=0; i<height; i++){
  298. 304 for(int j=0; j<width; j++){
  299. 305 fread(&pixel, 1, 2, fp);
  300. 306
  301. 307 the_image[i][j] = ((pixel.rgb565_struct.red<<3) +
  302. 308 (pixel.rgb565_struct.green<<2) +
  303. 309 (pixel.rgb565_struct.blue<<3)) / 3;
  304. 310 } /* ends loop over j */
  305. 311 if(pad != 0){
  306. 312 fseek(fp, pad, SEEK_CUR);
  307. 313 } /* ends if pad 1= 0 */
  308. 314 } /* ends loop over i */
  309. 315 }
  310. 316
  311. 317 void rgb5552grayscale(long height, long width, FILE* fp, short** the_image, int pad)
  312. 318 {
  313. 319 union rgb555_union pixel;
  314. 320
  315. 321 for(int i=0; i<height; i++){
  316. 322 for(int j=0; j<width; j++){
  317. 323 fread(&pixel, 1, 2, fp);
  318. 324 the_image[i][j] = ((pixel.rgb555_struct.red<<3) +
  319. 325 (pixel.rgb555_struct.green<<3) +
  320. 326 (pixel.rgb555_struct.blue<<3)) / 3;
  321. 327 } /* ends loop over j */
  322. 328 if(pad != 0){
  323. 329 fseek(fp, pad, SEEK_CUR);
  324. 330 } /* ends if pad 1= 0 */
  325. 331 } /* ends loop over i */
  326. 332 }
  327. 333
  328. 334 void bpp242grayscale(long height, long width, FILE* fp, short** the_image, int pad)
  329. 335 {
  330. 336 union bpp24_union pixel;
  331. 337
  332. 338 for(int i=0; i<height; i++){
  333. 339 for(int j=0; j<width; j++){
  334. 340 fread(&pixel, 1, 3, fp);
  335. 341 the_image[i][j] = ((pixel.bpp24_struct.red) +
  336. 342 (pixel.bpp24_struct.green) +
  337. 343 (pixel.bpp24_struct.blue)) / 3;
  338. 344 } /* ends loop over j */
  339. 345 if(pad != 0){
  340. 346 fseek(fp, pad, SEEK_CUR);
  341. 347 } /* ends if pad 1= 0 */
  342. 348 } /* ends loop over i */
  343. 349 }
  344. 350
  345. 351 void bpp322grayscale(long height, long width, FILE* fp, short** the_image, int pad)
  346. 352 {
  347. 353 union bpp32_union pixel;
  348. 354
  349. 355 for(int i=0; i<height; i++){
  350. 356 for(int j=0; j<width; j++){
  351. 357 fread(&pixel, 1, 4, fp);
  352. 358 the_image[i][j] = ((pixel.bpp32_struct.red) +
  353. 359 (pixel.bpp32_struct.green) +
  354. 360 (pixel.bpp32_struct.blue)) / 3;
  355. 361 } /* ends loop over j */
  356. 362 if(pad != 0){
  357. 363 fseek(fp, pad, SEEK_CUR);
  358. 364 } /* ends if pad 1= 0 */
  359. 365 } /* ends loop over i */
  360. 366 }
  361. 367
  362. 368 void flip_image_array(short** the_image, long rows, long cols)
  363. 369 {
  364. 370 int i, j;
  365. 371 long rd2;
  366. 372 short **temp;
  367. 373
  368. 374 temp = allocate_image_array(rows, cols);
  369. 375 rd2 = rows/2;
  370. 376 for(i=0; i<rd2; i++){
  371. 377 for(j=0; j<cols; j++){
  372. 378 temp[rows-1-i][j] = the_image[i][j];
  373. 379 } /* ends loop over j */
  374. 380 } /* ends loop over i */
  375. 381
  376. 382 for(i=rd2; i<rows; i++){
  377. 383 for(j=0; j<cols; j++){
  378. 384 temp[rows-1-i][j] = the_image[i][j];
  379. 385 } /* ends loop over j */
  380. 386 } /* ends loop over i */
  381. 387
  382. 388 for(i=0; i<rows; i++)
  383. 389 for(j=0; j<cols; j++)
  384. 390 the_image[i][j] = temp[i][j];
  385. 391
  386. 392 free_image_array(temp, rows);
  387. 393 } /* ends flip_image_array */
  388. 394
  389. 395 int get_image_size(const char* file_name, long* rows, long* cols)
  390. 396 {
  391. 397 struct bitmapheader bmph;
  392. 398
  393. 399 read_bm_header(file_name, &bmph);
  394. 400 *rows = bmph.height;
  395. 401 *cols = bmph.width;
  396. 402
  397. 403 return 1;
  398. 404 } /* ends get_image_size */
  399. 405
  400. 406 short **allocate_image_array(long length, long width)
  401. 407 {
  402. 408 int i;
  403. 409 short **the_array;
  404. 410
  405. 411 the_array = malloc(length * sizeof(short *));
  406. 412 for(i=0; i<length; i++){
  407. 413 the_array[i] = malloc(width * sizeof(short ));
  408. 414 if(the_array[i] == '\0'){
  409. 415 printf("\n\tmalloc of the_image[%d] failed", i);
  410. 416 } /* ends if */
  411. 417 } /* ends loop over i */
  412. 418 return(the_array);
  413. 419 } /* ends allocate_image_array */
  414. 420
  415. 421 int free_image_array(short **the_array, long length)
  416. 422 {
  417. 423 int i;
  418. 424 for(i=0; i<length; i++)
  419. 425 free(the_array[i]);
  420. 426 return(1);
  421. 427 } /* ends free_image_array */
  422. 428
  423. 429 int calculate_pad(long width)
  424. 430 {
  425. 431 int pad = 0;
  426. 432 pad = ( (width%4) == 0) ? 0 : (4-(width%4));
  427. 433 return(pad);
  428. 434 } /* ends calculate_pad */
  429. 435
  430. 436 void create_allocate_bmp_file(const char *file_name, struct bmpfileheader *file_header, struct bitmapheader *bmheader)
  431. 437 {
  432. 438 char buffer[100];
  433. 439 int i, pad = 0;
  434. 440 FILE *fp;
  435. 441
  436. 442 pad = calculate_pad(bmheader->width);
  437. 443
  438. 444 bmheader->size = 40;
  439. 445 bmheader->planes = 1;
  440. 446 bmheader->bitsperpixel = 8;
  441. 447 bmheader->compression = 0;
  442. 448 bmheader->sizeofbitmap = bmheader->height *
  443. 449 (bmheader->width + pad);
  444. 450 bmheader->horzres = 300;
  445. 451 bmheader->vertres = 300;
  446. 452 bmheader->colorsused = 256;
  447. 453 bmheader->colorsimp = 256;
  448. 454
  449. 455 file_header->filetype = 0x4D42;
  450. 456 file_header->reserved1 = 0;
  451. 457 file_header->reserved2 = 0;
  452. 458 file_header->bitmapoffset = 14 +
  453. 459 bmheader->size +
  454. 460 bmheader->colorsused*4;
  455. 461 file_header->filesize = file_header->bitmapoffset +
  456. 462 bmheader->sizeofbitmap;
  457. 463
  458. 464 if((fp = fopen(file_name, "wb")) == NULL){
  459. 465 printf("\nERROR Could not create file %s",
  460. 466 file_name);
  461. 467 exit(2);
  462. 468 }
  463. 469
  464. 470 insert_ushort_into_buffer(buffer, 0, file_header->filetype);
  465. 471 fwrite(buffer, 1, 2, fp);
  466. 472
  467. 473 insert_ulong_into_buffer(buffer, 0, file_header->filesize);
  468. 474 fwrite(buffer, 1, 4, fp);
  469. 475
  470. 476 insert_short_into_buffer(buffer, 0, file_header->reserved1);
  471. 477 fwrite(buffer, 1, 2, fp);
  472. 478
  473. 479 insert_short_into_buffer(buffer, 0, file_header->reserved2);
  474. 480 fwrite(buffer, 1, 2, fp);
  475. 481
  476. 482 insert_ulong_into_buffer(buffer, 0, file_header->bitmapoffset);
  477. 483 fwrite(buffer, 1, 4, fp);
  478. 484
  479. 485
  480. 486 /*********************************************
  481. 487 *
  482. 488 * Write the 40-byte bit map header.
  483. 489 *
  484. 490 *********************************************/
  485. 491
  486. 492 insert_ulong_into_buffer(buffer, 0, bmheader->size);
  487. 493 fwrite(buffer, 1, 4, fp);
  488. 494
  489. 495 insert_long_into_buffer(buffer, 0, bmheader->width);
  490. 496 fwrite(buffer, 1, 4, fp);
  491. 497
  492. 498 insert_long_into_buffer(buffer, 0, bmheader->height);
  493. 499 fwrite(buffer, 1, 4, fp);
  494. 500
  495. 501 insert_ushort_into_buffer(buffer, 0, bmheader->planes);
  496. 502 fwrite(buffer, 1, 2, fp);
  497. 503
  498. 504 insert_ushort_into_buffer(buffer, 0, bmheader->bitsperpixel);
  499. 505 fwrite(buffer, 1, 2, fp);
  500. 506
  501. 507 insert_ulong_into_buffer(buffer, 0, bmheader->compression);
  502. 508 fwrite(buffer, 1, 4, fp);
  503. 509
  504. 510 insert_ulong_into_buffer(buffer, 0, bmheader->sizeofbitmap);
  505. 511 fwrite(buffer, 1, 4, fp);
  506. 512
  507. 513 insert_ulong_into_buffer(buffer, 0, bmheader->horzres);
  508. 514 fwrite(buffer, 1, 4, fp);
  509. 515
  510. 516 insert_ulong_into_buffer(buffer, 0, bmheader->vertres);
  511. 517 fwrite(buffer, 1, 4, fp);
  512. 518
  513. 519 insert_ulong_into_buffer(buffer, 0, bmheader->colorsused);
  514. 520 fwrite(buffer, 1, 4, fp);
  515. 521
  516. 522 insert_ulong_into_buffer(buffer, 0, bmheader->colorsimp);
  517. 523 fwrite(buffer, 1, 4, fp);
  518. 524
  519. 525 /*********************************************
  520. 526 *
  521. 527 * Write a blank color table.
  522. 528 * It has 256 entries (number of colors)
  523. 529 * that are each 4 bytes.
  524. 530 *
  525. 531 *********************************************/
  526. 532
  527. 533 buffer[0] = 0x00;
  528. 534
  529. 535 for(i=0; i<(256*4); i++)
  530. 536 fwrite(buffer, 1, 1, fp);
  531. 537
  532. 538 /*********************************************
  533. 539 *
  534. 540 * Write a zero image.
  535. 541 *
  536. 542 *********************************************/
  537. 543
  538. 544 buffer[0] = 0x00;
  539. 545
  540. 546 for(i=0; i<bmheader->sizeofbitmap; i++)
  541. 547 fwrite(buffer, 1, 1, fp);
  542. 548
  543. 549 fclose(fp);
  544. 550 } /* ends create_allocate_bmp_file */
  545. 551
  546. 552 void write_bmp_image(const char* file_name, short **array)
  547. 553 {
  548. 554 char *buffer;
  549. 555 FILE *image_file;
  550. 556 int pad = 0;
  551. 557 int i, j;
  552. 558 long height = 0, width = 0;
  553. 559 struct bitmapheader bmheader;
  554. 560 struct bmpfileheader file_header;
  555. 561 struct ctstruct rgb[GRAY_LEVELS+1];
  556. 562 union short_char_union scu;
  557. 563
  558. 564 read_bmp_file_header(file_name, &file_header);
  559. 565 read_bm_header(file_name, &bmheader);
  560. 566
  561. 567 height = bmheader.height;
  562. 568 width = bmheader.width;
  563. 569 if(height < 0)
  564. 570 height = height*(-1);
  565. 571
  566. 572 buffer = (char *) malloc(width * sizeof(char ));
  567. 573 for(i=0; i<width; i++)
  568. 574 buffer[i] = '\0';
  569. 575
  570. 576 image_file = fopen(file_name, "rb+");
  571. 577
  572. 578 /****************************************
  573. 579 *
  574. 580 * Write the color table first.
  575. 581 *
  576. 582 ****************************************/
  577. 583
  578. 584 fseek(image_file, 54, SEEK_SET);
  579. 585 for(i=0; i<GRAY_LEVELS+1; i++){
  580. 586 rgb[i].blue = i;
  581. 587 rgb[i].green = i;
  582. 588 rgb[i].red = i;
  583. 589 } /* ends loop over i */
  584. 590
  585. 591 for(i=0; i<bmheader.colorsused; i++){
  586. 592 buffer[0] = rgb[i].blue;
  587. 593 fwrite(buffer , 1, 1, image_file);
  588. 594 buffer[0] = rgb[i].green;
  589. 595 fwrite(buffer , 1, 1, image_file);
  590. 596 buffer[0] = rgb[i].red;
  591. 597 fwrite(buffer , 1, 1, image_file);
  592. 598 buffer[0] = 0x00;
  593. 599 fwrite(buffer , 1, 1, image_file);
  594. 600 } /* ends loop over i */
  595. 601
  596. 602 fseek(image_file, file_header.bitmapoffset, SEEK_SET);
  597. 603
  598. 604 pad = calculate_pad(width);
  599. 605
  600. 606 for(i=0; i<height; i++){
  601. 607 for(j=0; j<width; j++){
  602. 608
  603. 609 if(bmheader.bitsperpixel == 8){
  604. 610 scu.s_num = 0;
  605. 611 if(bmheader.height > 0)
  606. 612 scu.s_num = array[height-1-i][j];
  607. 613 else
  608. 614 scu.s_num = array[i][j];
  609. 615 buffer[j] = scu.s_alpha[0];
  610. 616 } /* ends if bits_per_pixel == 8 */
  611. 617 else{
  612. 618 printf("\nERROR bitsperpixel is not 8");
  613. 619 exit(1);
  614. 620 }
  615. 621 } /* ends loop over j */
  616. 622
  617. 623 fwrite(buffer, 1, width, image_file);
  618. 624
  619. 625 if(pad != 0){
  620. 626 for(j=0; j<pad; j++)
  621. 627 buffer[j] = 0x00;
  622. 628 fwrite(buffer, 1, pad, image_file);
  623. 629 } /* ends if pad != 0 */
  624. 630
  625. 631 } /* ends loop over i */
  626. 632
  627. 633 fclose(image_file);
  628. 634 free(buffer);
  629. 635 } /* ends write_bmp_image */
  630. 636
  631. 637 void read_bmp_file_header(const char *file_name, struct bmpfileheader *file_header)
  632. 638 {
  633. 639 char buffer[10];
  634. 640 short ss;
  635. 641 unsigned long ull;
  636. 642 unsigned short uss;
  637. 643 FILE *fp;
  638. 644
  639. 645 fp = fopen(file_name, "rb");
  640. 646
  641. 647 fread(buffer, 1, 2, fp);
  642. 648 extract_ushort_from_buffer(buffer, 1, 0, &uss);
  643. 649 file_header->filetype = uss;
  644. 650
  645. 651 fread(buffer, 1, 4, fp);
  646. 652 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  647. 653 file_header->filesize = ull;
  648. 654
  649. 655 fread(buffer, 1, 2, fp);
  650. 656 extract_short_from_buffer(buffer, 1, 0, &ss);
  651. 657 file_header->reserved1 = ss;
  652. 658
  653. 659 fread(buffer, 1, 2, fp);
  654. 660 extract_short_from_buffer(buffer, 1, 0, &ss);
  655. 661 file_header->reserved2 = ss;
  656. 662
  657. 663 fread(buffer, 1, 4, fp);
  658. 664 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  659. 665 file_header->bitmapoffset = ull;
  660. 666
  661. 667 fclose(fp);
  662. 668
  663. 669 } /* ends read_bmp_file_header */
  664. 670
  665. 671 void read_bm_header(const char* file_name, struct bitmapheader *bmheader)
  666. 672 {
  667. 673 char buffer[10];
  668. 674 long ll;
  669. 675 unsigned long ull;
  670. 676 unsigned short uss;
  671. 677 FILE *fp;
  672. 678
  673. 679 fp = fopen(file_name, "rb");
  674. 680
  675. 681 /****************************************
  676. 682 *
  677. 683 * Seek past the first 14 byte header.
  678. 684 *
  679. 685 ****************************************/
  680. 686
  681. 687 fseek(fp, 14, SEEK_SET);
  682. 688
  683. 689 fread(buffer, 1, 4, fp);
  684. 690 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  685. 691 bmheader->size = ull;
  686. 692
  687. 693 fread(buffer, 1, 4, fp);
  688. 694 extract_long_from_buffer(buffer, 1, 0, &ll);
  689. 695 bmheader->width = ll;
  690. 696
  691. 697 fread(buffer, 1, 4, fp);
  692. 698 extract_long_from_buffer(buffer, 1, 0, &ll);
  693. 699 bmheader->height = ll;
  694. 700
  695. 701 fread(buffer, 1, 2, fp);
  696. 702 extract_ushort_from_buffer(buffer, 1, 0, &uss);
  697. 703 bmheader->planes = uss;
  698. 704
  699. 705 fread(buffer, 1, 2, fp);
  700. 706 extract_ushort_from_buffer(buffer, 1, 0, &uss);
  701. 707 bmheader->bitsperpixel = uss;
  702. 708
  703. 709 fread(buffer, 1, 4, fp);
  704. 710 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  705. 711 bmheader->compression = ull;
  706. 712
  707. 713 fread(buffer, 1, 4, fp);
  708. 714 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  709. 715 bmheader->sizeofbitmap = ull;
  710. 716
  711. 717 fread(buffer, 1, 4, fp);
  712. 718 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  713. 719 bmheader->horzres = ull;
  714. 720
  715. 721 fread(buffer, 1, 4, fp);
  716. 722 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  717. 723 bmheader->vertres = ull;
  718. 724
  719. 725 fread(buffer, 1, 4, fp);
  720. 726 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  721. 727 bmheader->colorsused = ull;
  722. 728
  723. 729 fread(buffer, 1, 4, fp);
  724. 730 extract_ulong_from_buffer(buffer, 1, 0, &ull);
  725. 731 bmheader->colorsimp = ull;
  726. 732
  727. 733 fclose(fp);
  728. 734 } /* ends read_bm_header */
  729. 735
  730. 736 void extract_long_from_buffer(char buffer[], int lsb, int start, long* number)
  731. 737 {
  732. 738 union long_char_union lcu;
  733. 739
  734. 740 if(lsb == 1){
  735. 741 lcu.l_alpha[0] = buffer[start+0];
  736. 742 lcu.l_alpha[1] = buffer[start+1];
  737. 743 lcu.l_alpha[2] = buffer[start+2];
  738. 744 lcu.l_alpha[3] = buffer[start+3];
  739. 745 } /* ends if lsb = 1 */
  740. 746
  741. 747 if(lsb == 0){
  742. 748 lcu.l_alpha[0] = buffer[start+3];
  743. 749 lcu.l_alpha[1] = buffer[start+2];
  744. 750 lcu.l_alpha[2] = buffer[start+1];
  745. 751 lcu.l_alpha[3] = buffer[start+0];
  746. 752 } /* ends if lsb = 0 */
  747. 753
  748. 754 *number = lcu.l_num;
  749. 755 } /* ends extract_long_from_buffer */
  750. 756
  751. 757 void extract_ulong_from_buffer(char buffer[], int lsb, int start,unsigned long* number)
  752. 758 {
  753. 759 union ulong_char_union lcu;
  754. 760
  755. 761 if(lsb == 1){
  756. 762 lcu.l_alpha[0] = buffer[start+0];
  757. 763 lcu.l_alpha[1] = buffer[start+1];
  758. 764 lcu.l_alpha[2] = buffer[start+2];
  759. 765 lcu.l_alpha[3] = buffer[start+3];
  760. 766 } /* ends if lsb = 1 */
  761. 767
  762. 768 if(lsb == 0){
  763. 769 lcu.l_alpha[0] = buffer[start+3];
  764. 770 lcu.l_alpha[1] = buffer[start+2];
  765. 771 lcu.l_alpha[2] = buffer[start+1];
  766. 772 lcu.l_alpha[3] = buffer[start+0];
  767. 773 } /* ends if lsb = 0 */
  768. 774 *number = lcu.l_num;
  769. 775 } /* ends extract_ulong_from_buffer */
  770. 776
  771. 777 void extract_short_from_buffer(char buffer[], int lsb, int start, short* number)
  772. 778 {
  773. 779 union short_char_union lcu;
  774. 780
  775. 781 if(lsb == 1){
  776. 782 lcu.s_alpha[0] = buffer[start+0];
  777. 783 lcu.s_alpha[1] = buffer[start+1];
  778. 784 } /* ends if lsb = 1 */
  779. 785
  780. 786 if(lsb == 0){
  781. 787 lcu.s_alpha[0] = buffer[start+1];
  782. 788 lcu.s_alpha[1] = buffer[start+0];
  783. 789 } /* ends if lsb = 0 */
  784. 790
  785. 791 *number = lcu.s_num;
  786. 792 } /* ends extract_short_from_buffer */
  787. 793
  788. 794 void extract_ushort_from_buffer(char buffer[], int lsb, int start, unsigned short* number)
  789. 795 {
  790. 796 union ushort_char_union lcu;
  791. 797
  792. 798 if(lsb == 1){
  793. 799 lcu.s_alpha[0] = buffer[start+0];
  794. 800 lcu.s_alpha[1] = buffer[start+1];
  795. 801 } /* ends if lsb = 1 */
  796. 802
  797. 803 if(lsb == 0){
  798. 804 lcu.s_alpha[0] = buffer[start+1];
  799. 805 lcu.s_alpha[1] = buffer[start+0];
  800. 806 } /* ends if lsb = 0 */
  801. 807
  802. 808 *number = lcu.s_num;
  803. 809 } /* ends extract_ushort_from_buffer */
  804. 810
  805. 811 void insert_short_into_buffer(char buffer[], int start, short number)
  806. 812 {
  807. 813 union short_char_union lsu;
  808. 814
  809. 815 lsu.s_num = number;
  810. 816 buffer[start+0] = lsu.s_alpha[0];
  811. 817 buffer[start+1] = lsu.s_alpha[1];
  812. 818
  813. 819 } /* ends insert_short_into_buffer */
  814. 820
  815. 821 void insert_ushort_into_buffer(char buffer[], int start, unsigned short number)
  816. 822 {
  817. 823 union ushort_char_union lsu;
  818. 824
  819. 825 lsu.s_num = number;
  820. 826 buffer[start+0] = lsu.s_alpha[0];
  821. 827 buffer[start+1] = lsu.s_alpha[1];
  822. 828 } /* ends insert_short_into_buffer */
  823. 829
  824. 830 void insert_long_into_buffer(char buffer[], int start, long number)
  825. 831 {
  826. 832 union long_char_union lsu;
  827. 833
  828. 834 lsu.l_num = number;
  829. 835 buffer[start+0] = lsu.l_alpha[0];
  830. 836 buffer[start+1] = lsu.l_alpha[1];
  831. 837 buffer[start+2] = lsu.l_alpha[2];
  832. 838 buffer[start+3] = lsu.l_alpha[3];
  833. 839 } /* ends insert_short_into_buffer */
  834. 840
  835. 841 void insert_ulong_into_buffer(char buffer[], int start, unsigned long number)
  836. 842 {
  837. 843 union ulong_char_union lsu;
  838. 844
  839. 845 lsu.l_num = number;
  840. 846 buffer[start+0] = lsu.l_alpha[0];
  841. 847 buffer[start+1] = lsu.l_alpha[1];
  842. 848 buffer[start+2] = lsu.l_alpha[2];
  843. 849 buffer[start+3] = lsu.l_alpha[3];
  844. 850 } /* ends insert_ulong_into_buffer */
  845. 851
  846. 852 int does_not_exist(const char* file_name)
  847. 853 {
  848. 854 FILE *image_file;
  849. 855 int result;
  850. 856
  851. 857 result = 1;
  852. 858 image_file = fopen(file_name, "rb");
  853. 859 if(image_file != NULL){
  854. 860 result = 0;
  855. 861 fclose(image_file);
  856. 862 }
  857. 863 return(result);
  858. 864 } /* ends does_not_exist */

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号