经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
C语言实现BMP格式图片转化为灰度
来源:jb51  时间:2021/10/25 19:07:50  对本文有异议

本文实例为大家分享了C语言将BMP格式图片转化为灰度的具体代码,供大家参考,具体内容如下

代码如下:

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<stdlib.h>
  4. #pragma pack(1)
  5. typedef struct tagBITMAPFILEHEADER
  6. {
  7. unsigned char bfType[2];//文件格式
  8. unsigned long bfSize;//文件大小
  9. unsigned short bfReserved1;//保留
  10. unsigned short bfReserved2;
  11. unsigned long bfOffBits; //DIB数据在文件中的偏移量
  12. }fileHeader;
  13. #pragma pack()
  14. /*
  15. 位图数据信息结构
  16. */
  17. #pragma pack(1)
  18. typedef struct tagBITMAPINFOHEADER
  19. {
  20. unsigned long biSize;//该结构的大小
  21. long biWidth;//文件宽度
  22. long biHeight;//文件高度
  23. unsigned short biPlanes;//平面数
  24. unsigned short biBitCount;//颜色位数
  25. unsigned long biCompression;//压缩类型
  26. unsigned long biSizeImage;//DIB数据区大小
  27. long biXPixPerMeter;
  28. long biYPixPerMeter;
  29. unsigned long biClrUsed;//多少颜色索引表
  30. unsigned long biClrImporant;//多少重要颜色
  31. }fileInfo;
  32. #pragma pack()
  33. /*
  34. 调色板结构
  35. */
  36. #pragma pack(1)
  37. typedef struct tagRGBQUAD
  38. {
  39. unsigned char rgbBlue; //蓝色分量亮度
  40. unsigned char rgbGreen;//绿色分量亮度
  41. unsigned char rgbRed;//红色分量亮度
  42. unsigned char rgbReserved;
  43. }rgbq;
  44. #pragma pack()
  45. int main()
  46. {
  47. FILE *fp1 = fopen("C:\\Users\\Administrator\\Desktop\\data\\bmp\\image.bmp", "rb+");
  48. if (fp1 == NULL)
  49. {
  50. printf("打开文件fp1失败");
  51. exit(0);
  52. }
  53. FILE *fp2 = fopen("C:\\Users\\Administrator\\Desktop\\data\\bmp\\imageGray.bmp", "wb");
  54. if (fp1 == NULL)
  55. {
  56. printf("打开文件fp2失败");
  57. exit(0);
  58. }
  59. fileHeader * fh;
  60. fileInfo * fi;
  61. fh = (fileHeader *)malloc(sizeof(fileHeader));
  62. fi = (fileInfo *)malloc(sizeof(fileInfo));
  63. //读取位图头结构和信息头
  64. fread(fh, sizeof(fileHeader), 1, fp1);
  65. fread(fi, sizeof(fileInfo), 1, fp1);
  66. printf("\\\\\\\\\\\\\\\\\\\\原始图片信息\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
  67. printf("bmp文件头:\n");
  68. printf("bfSize:%d\n", fh->bfSize);
  69. printf("bfOffBits:%d\n", fh->bfOffBits);
  70. printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
  71. printf("bmp信息头\n");
  72. printf("结构体长度:%d \n", fi->biSize);
  73. printf("位图宽度:%d \n", fi->biWidth);
  74. printf("位图高度:%d \n", fi->biHeight);
  75. printf("位图平面数:%d \n", fi->biPlanes);
  76. printf("颜色位数:%d \n", fi->biBitCount);
  77. printf("压缩方式:%d \n", fi->biCompression);
  78. printf("实际位图数据占用的字节数:%d \n", fi->biSizeImage);
  79. printf("X方向分辨率:%d \n", fi->biXPixPerMeter);
  80. printf("Y方向分辨率:%d \n", fi->biYPixPerMeter);
  81. printf("使用的颜色数:%d \n", fi->biClrUsed);
  82. printf("重要颜色数:%d \n", fi->biClrImporant);
  83. printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
  84. //修改信息头
  85. fi->biBitCount = 8;
  86. //fi->biSizeImage = ((fi->biWidth * 3 + 3) / 4) * 4 * fi->biHeight;
  87. fi->biSizeImage = fi->biHeight*fi->biWidth;
  88. //修改文件头
  89. fh->bfOffBits = sizeof(fileHeader) + sizeof(fileInfo) + 256 * sizeof(rgbq);
  90. fh->bfSize = fh->bfOffBits + fi->biSizeImage;
  91. printf("\\\\\\\\\\\\\\\\\\\\修改后的图片信息\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
  92. printf("bmp文件头:\n");
  93. printf("bfSize:%d\n", fh->bfSize);
  94. printf("bfOffBits:%d\n", fh->bfOffBits);
  95. printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
  96. printf("bmp信息头\n");
  97. printf("结构体长度:%d \n", fi->biSize);
  98. printf("位图宽度:%d \n", fi->biWidth);
  99. printf("位图高度:%d \n", fi->biHeight);
  100. printf("位图平面数:%d \n", fi->biPlanes);
  101. printf("颜色位数:%d \n", fi->biBitCount);
  102. printf("压缩方式:%d \n", fi->biCompression);
  103. printf("实际位图数据占用的字节数:%d \n", fi->biSizeImage);
  104. printf("X方向分辨率:%d \n", fi->biXPixPerMeter);
  105. printf("Y方向分辨率:%d \n", fi->biYPixPerMeter);
  106. printf("使用的颜色数:%d \n", fi->biClrUsed);
  107. printf("重要颜色数:%d \n", fi->biClrImporant);
  108. printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
  109. //创建调色板
  110. int i,j,k=0;
  111. rgbq *fq = (rgbq *)malloc(256 * sizeof(rgbq));
  112. for (i = 0; i<256; i++)
  113. {
  114. fq[i].rgbBlue = fq[i].rgbGreen = fq[i].rgbRed = i;
  115. }
  116. //写入文件头、信息头、调色板
  117. fwrite(fh, sizeof(fileHeader), 1, fp2);
  118. fwrite(fi, sizeof(fileInfo), 1, fp2);
  119. fwrite(fq, sizeof(rgbq), 256, fp2);
  120. //将位图信息转为灰度
  121. //存储bmp一行的像素点
  122. //unsigned char ImgData[900][3];
  123. unsigned char ImgData[3000][3];
  124. //将灰度图像存到一维数组中
  125. //unsigned char grayData2[900];
  126. unsigned char ImgData2[3000];
  127. /*
  128. //错误的算法
  129. for (i = 0; i < fi->biHeight; i++)
  130. {
  131. for (j = 0; j < (fi->biWidth * 3 + 3) / 4 * 4; j++)
  132. {
  133. for (k = 0; k < 3; k++)
  134. {
  135. fread(&ImgData[j][k], 1, 1, fp1);
  136. }
  137. }
  138. for (j = 0; j < (fi->biWidth + 3) / 4 * 4; j++)
  139. {
  140. ImgData2[j] = int((float)ImgData[j][0] * 0.114 +
  141. (float)ImgData[j][1] * 0.587 +
  142. (float)ImgData[j][2] * 0.299);
  143. }
  144. //将灰度图信息写入
  145. fwrite(ImgData2, j, 1, fp2);
  146. }
  147. */
  148. /*
  149. //正确的算法(1)
  150. for (i = 0; i<fi->biHeight; i++)
  151. {
  152. for (j = 0; j<(fi->biWidth + 3) / 4 * 4; j++)
  153. {
  154. for (k = 0; k<3; k++)
  155. fread(&ImgData[j][k], 1, 1, fp1);
  156. }
  157. for (j = 0; j<(fi->biWidth + 3) / 4 * 4; j++)
  158. {
  159. ImgData2[j] = int((float)ImgData[j][0] * 0.114 +
  160. (float)ImgData[j][1] * 0.587 +
  161. (float)ImgData[j][2] * 0.299);
  162. }
  163. //将灰度图信息写入
  164. fwrite(ImgData2, j, 1, fp2);
  165. }
  166. */
  167. //正确算法(2)
  168. unsigned char * * bmp_data;
  169. bmp_data = new unsigned char*[fi->biHeight]; //声明一个指针数组
  170. unsigned char *data288 = new unsigned char[fi->biHeight*fi->biWidth];
  171. for (i = 0; i<fi->biHeight; i++)
  172. bmp_data[i] = new unsigned char[(fi->biWidth * 3 + 3) / 4 * 4]; //每个数组元素也是一个指针数组
  173. for (i = 0; i<fi->biHeight; i++)
  174. for (j = 0; j<(fi->biWidth * 3 + 3) / 4 * 4; j++)
  175. fread(&bmp_data[i][j], 1, 1, fp1);//每次只读取一个字节,存入数组
  176. for (i = 0; i<fi->biHeight; i++)//将24位真彩色转换成灰度图
  177. for (j = 0; j<fi->biWidth; j++){
  178. data288[fi->biWidth*i + j] = ((unsigned char)((float)bmp_data[i][3 * j] * 0.114 + (float)bmp_data[i][3 * j + 1] * 0.587 + (float)bmp_data[i][3 * j + 2] * 0.299));
  179. }
  180. fwrite(data288, fi->biSizeImage, 1, fp2);
  181. free(fh);
  182. free(fi);
  183. free(fq);
  184. fclose(fp1);
  185. fclose(fp2);
  186. printf("success\n");
  187. return 0;
  188. }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

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

本站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号