c语言实现BMP图像转换为灰度图

当初是自己要装X,非要用c来写信息隐藏作业,装了X,就得付出实践。查了好久资料,到期末才把作业交了,这里总结一下。

这道题是将真彩图转换为灰度图

  • 关于BMP文件结构,这是困扰了我好久的问题,上网查了很久图片的知识才弄明白
  • BMP文件包括以下几部分(具体结构在程序中说明):
    • 位图文件头
    • 位图信息头
    • 调色板
    • 位图数据
  • 结构体内存对齐原则
    • 每个成员存储的起始位置要从该成员大小的整数倍开始
    • 成员是结构体时相对与起始偏移是其内部最大元素大小的整数倍
    • 结构体的总大小是其内部最大成员的整数倍
  • 因此在定义头结构的时候要加上#pragma pack(1),设置以1字节为对齐方式,不然后面数据会错位
  1 /*

  2 真彩图转换成灰度图的改进版

  3 (不把真彩图的每个像素点放入二维矩阵,而是读一行写一行)

  4 blog:http://www.cnblogs.com/wd1001/

  5 2015年6月2日19:04:09

  6 */

  7 #include<stdio.h>

  8 #include<malloc.h>

  9 #include<stdlib.h>

 10 /*

 11 位图头结构

 12 */

 13 #pragma pack(1)

 14 typedef struct tagBITMAPFILEHEADER

 15 {

 16     unsigned char bfType[2];//文件格式

 17     unsigned long bfSize;//文件大小

 18     unsigned short bfReserved1;//保留

 19     unsigned short bfReserved2;

 20     unsigned long bfOffBits; //DIB数据在文件中的偏移量

 21 }fileHeader;

 22 #pragma pack()

 23 /*

 24 位图数据信息结构

 25 */

 26 #pragma pack(1)

 27 typedef struct tagBITMAPINFOHEADER

 28 {

 29     unsigned long biSize;//该结构的大小

 30     long biWidth;//文件宽度

 31     long biHeight;//文件高度

 32     unsigned short biPlanes;//平面数

 33     unsigned short biBitCount;//颜色位数

 34     unsigned long biCompression;//压缩类型

 35     unsigned long biSizeImage;//DIB数据区大小

 36     long biXPixPerMeter;

 37     long biYPixPerMeter;

 38     unsigned long biClrUsed;//多少颜色索引表

 39     unsigned long biClrImporant;//多少重要颜色

 40 }fileInfo;

 41 #pragma pack()

 42 /*

 43 调色板结构

 44 */

 45 #pragma pack(1)

 46 typedef struct tagRGBQUAD

 47 {

 48     unsigned char rgbBlue; //蓝色分量亮度

 49     unsigned char rgbGreen;//绿色分量亮度

 50     unsigned char rgbRed;//红色分量亮度

 51     unsigned char rgbReserved;

 52 }rgbq;

 53 #pragma pack()

 54 

 55 int main()

 56 {

 57     /*存储RGB图像的一行像素点*/

 58     unsigned char ImgData[3000][3];

 59     /*将灰度图的像素存到一个一维数组中*/

 60     unsigned char ImgData2[3000];

 61     int i,j,k;

 62     FILE * fpBMP,* fpGray;

 63     fileHeader * fh;

 64     fileInfo * fi;

 65     rgbq * fq;

 66     

 67     if((fpBMP=fopen("G:/vc6.0/work/21.bmp","rb"))==NULL)

 68     {

 69         printf("打开文件失败");

 70         exit(0);

 71     }

 72     

 73     if((fpGray=fopen("G:/vc6.0/work/22.bmp","wb"))==NULL)

 74     {

 75         printf("创建文件失败");

 76         exit(0);

 77     }

 78     

 79     fh=(fileHeader *)malloc(sizeof(fileHeader));

 80     fi=(fileInfo *)malloc(sizeof(fileInfo));

 81     //读取位图头结构和信息头

 82     fread(fh,sizeof(fileHeader),1,fpBMP);

 83     fread(fi,sizeof(fileInfo),1,fpBMP);

 84     //修改头信息

 85     fi->biBitCount=8;

 86     fi->biSizeImage=( (fi->biWidth*3+3)/4 ) * 4*fi->biHeight;

 87     //fi->biClrUsed=256;

 88     

 89     fh->bfOffBits = sizeof(fileHeader)+sizeof(fileInfo)+256*sizeof(rgbq);

 90     fh->bfSize = fh->bfOffBits + fi->biSizeImage;

 91     

 92     //创建调色版

 93     fq=(rgbq *)malloc(256*sizeof(rgbq));

 94     for(i=0;i<256;i++)

 95     {

 96         fq[i].rgbBlue=fq[i].rgbGreen=fq[i].rgbRed=i;

 97         //fq[i].rgbReserved=0;

 98     }

 99     //将头信息写入

100     fwrite(fh,sizeof(fileHeader),1,fpGray);  

101     fwrite(fi,sizeof(fileInfo),1,fpGray); 

102     fwrite(fq,sizeof(rgbq),256,fpGray);

103     //读取RGB图像素并转换为灰度值

104     for ( i=0;i<fi->biHeight;i++ )

105     {

106         for(j=0;j<(fi->biWidth+3)/4*4;j++)

107         {

108             for(k=0;k<3;k++)

109                 fread(&ImgData[j][k],1,1,fpBMP);

110         }

111         for(j=0;j<(fi->biWidth+3)/4*4;j++)

112         {

113             ImgData2[j]=int( (float)ImgData[j][0] * 0.114 +

114                         (float)ImgData[j][1] * 0.587 +

115                         (float)ImgData[j][2] * 0.299 );

116         }

117         //将灰度图信息写入

118         fwrite(ImgData2,j,1,fpGray);

119     }   

120         

121         free(fh);

122         free(fi);

123         free(fq);

124         fclose(fpBMP);

125         fclose(fpGray);

126         printf("success\n");

127         return 0;

128 }

结果:

c语言实现BMP图像转换为灰度图c语言实现BMP图像转换为灰度图

你可能感兴趣的:(C语言)