码迷,mamicode.com
首页 > 编程语言 > 详细

c语言数字图像处理(一):bmp图片格式及灰度图片转换

时间:2018-09-09 19:56:59      阅读:497      评论:0      收藏:0      [点我收藏+]

标签:limited   array   trie   hat   first   res   abi   alt   灰度   

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

 

c语言数字图像处理(一):bmp图片格式及灰度图片转换

标签:limited   array   trie   hat   first   res   abi   alt   灰度   

原文地址:https://www.cnblogs.com/GoldBeetle/p/9614287.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!