博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c语言实现BMP图像转换为灰度图
阅读量:4082 次
发布时间:2019-05-25

本文共 3782 字,大约阅读时间需要 12 分钟。

转载自:

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

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

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

复制代码

1 /*  2 真彩图转换成灰度图的改进版  3 (不把真彩图的每个像素点放入二维矩阵,而是读一行写一行)  4 blog:http://www.cnblogs.com/wd1001/  5 2015年6月2日19:04:09  6 */  7 #include
8 #include
9 #include
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
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 }

复制代码

结果:

你可能感兴趣的文章
SpringCloud学习之PassCloud——(一)PassCloud源代码下载
查看>>
Linux下安装Python环境并部署NLP项目
查看>>
Nginx篇-springCloud配置Gateway+Nginx进行反向代理和负载均衡
查看>>
Nginx篇-Nginx配置动静分离
查看>>
缓存篇-Redis缓存失效以及解决方案
查看>>
缓存篇-使用Redis进行分布式锁应用
查看>>
缓存篇-Redisson的使用
查看>>
phpquery抓取网站内容简单介绍
查看>>
找工作准备的方向(4月22日写的)
查看>>
关于fwrite写入文件后打开查看是乱码的问题
查看>>
用结构体指针前必须要用malloc,不然会出现段错误
查看>>
Linux系统中的美
查看>>
一些实战项目(linux应用层编程,多线程编程,网络编程)
查看>>
我觉得专注于去学东西就好了,与世无争。
查看>>
原来k8s docker是用go语言写的,和现在所讲的go是一个东西!
查看>>
STM32CubeMX 真的不要太好用
查看>>
STM32CubeMX介绍、下载与安装
查看>>
电机和桨叶要搭配选择
查看>>
不要买铝合金机架的无人机,不耐摔,易变形弯曲。
查看>>
ACfly也是基于FreeRTOS的
查看>>