C语言编写的bmp读写程序

C语言编写的bmp读写程序 建议先把bmp的数据存储格式了解下

[cpp] view plaincopy

  1. <span style="font-size:16px;">#include "Windows.h"

  2. #include "stdio.h"

  3. #include "string.h"

  4. #include "malloc.h"
  5. unsigned char *pBmpBuf;//读入图像数据的指针

  6. int bmpWidth;//图像的宽

  7. int bmpHeight;//图像的高

  8. RGBQUAD *pColorTable;//颜色表指针

  9. int biBitCount;//图像类型,每像素位数
  10. bool readBmp(char *bmpName)

  11. {

  12. //二进制读方式打开指定的图像文件

  13. FILE *fp=fopen(bmpName,"rb");

  14. if(fp==0) return 0;
  15. //跳过位图文件头结构BITMAPFILEHEADER

  16. fseek(fp, sizeof(BITMAPFILEHEADER),0);

  17. //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中

  18. BITMAPINFOHEADER head;

  19. fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);

  20. //获取图像宽、高、每像素所占位数等信息

  21. bmpWidth = head.biWidth;

  22. bmpHeight = head.biHeight;

  23. biBitCount = head.biBitCount;

  24. //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)

  25. int lineByte=(bmpWidth * biBitCount/8+3)/4*4;

  26. //灰度图像有颜色表,且颜色表表项为256

  27. if(biBitCount==8){

  28. //申请颜色表所需要的空间,读颜色表进内存

  29. pColorTable=new RGBQUAD[256];

  30. fread(pColorTable,sizeof(RGBQUAD),256,fp);

  31. }

  32. //申请位图数据所需要的空间,读位图数据进内存

  33. pBmpBuf=new unsigned char[lineByte * bmpHeight];

  34. fread(pBmpBuf,1,lineByte * bmpHeight,fp);

  35. //关闭文件

  36. fclose(fp);

  37. return 1;

  38. }
  39. bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height,

  40. int biBitCount, RGBQUAD *pColorTable)

  41. {

  42. //如果位图数据指针为0,则没有数据传入,函数返回

  43. if(!imgBuf)

  44. return 0;

  45. //颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0

  46. int colorTablesize=0;

  47. if(biBitCount==8)

  48. colorTablesize=1024;

  49. //待存储图像数据每行字节数为4的倍数

  50. int lineByte=(width * biBitCount/8+3)/4*4;

  51. //以二进制写的方式打开文件

  52. FILE *fp=fopen(bmpName,"wb");

  53. if(fp==0) return 0;

  54. //申请位图文件头结构变量,填写文件头信息

  55. BITMAPFILEHEADER fileHead;

  56. fileHead.bfType = 0x4D42;//bmp类型

  57. //bfSize是图像文件4个组成部分之和

  58. fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)

  59. + colorTablesize + lineByte*height;

  60. fileHead.bfReserved1 = 0;

  61. fileHead.bfReserved2 = 0;

  62. //bfOffBits是图像文件前3个部分所需空间之和

  63. fileHead.bfOffBits=54+colorTablesize;

  64. //写文件头进文件

  65. fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);

  66. //申请位图信息头结构变量,填写信息头信息

  67. BITMAPINFOHEADER head;

  68. head.biBitCount=biBitCount;

  69. head.biClrImportant=0;

  70. head.biClrUsed=0;

  71. head.biCompression=0;

  72. head.biHeight=height;

  73. head.biPlanes=1;

  74. head.biSize=40;

  75. head.biSizeImage=lineByte*height;

  76. head.biWidth=width;

  77. head.biXPelsPerMeter=0;

  78. head.biYPelsPerMeter=0;

  79. //写位图信息头进内存

  80. fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);

  81. //如果灰度图像,有颜色表,写入文件

  82. if(biBitCount==8)

  83. fwrite(pColorTable, sizeof(RGBQUAD),256, fp);

  84. //写位图数据进文件

  85. fwrite(imgBuf, height*lineByte, 1, fp);

  86. //关闭文件

  87. fclose(fp);

  88. return 1;

  89. }
  90. void main()

  91. {

  92. char inFileName[90],outFileName[90];

  93. printf("请输入原始位图文件的文件名:");

  94. scanf("%s",inFileName);

  95. printf("请输入加密程序产生的新位图文件的文件名:");

  96. scanf("%s",outFileName);

  97. //读入指定BMP文件进内存

  98. readBmp(inFileName);

  99. //输出图像的信息

  100. printf("width=%d,height=%d, biBitCount=%d\n",bmpWidth,bmpHeight, biBitCount);

  101. //将图像数据存盘

  102. saveBmp(outFileName, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable);

  103. //清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间

  104. delete []pBmpBuf;

  105. if(biBitCount==8)

  106. delete []pColorTable;

  107. }

  108. </span>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

一、BMP文件结构 

BMP文件组成 
BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
  
BMP文件头 
BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。
  
其结构定义如下: 
typedef   struct  
tagBITMAPFILEHEADER 

WORDbfType;   //  
位图文件的类型,必须为BM 
DWORD   bfSize;   //   位图文件的大小,以字节为单位
  
WORDbfReserved1;   //  
位图文件保留字,必须为0 
WORDbfReserved2;   //  
位图文件保留字,必须为0 
DWORD   bfOffBits;   //  
位图数据的起始位置,以相对于位图 
//   文件头的偏移量表示,以字节为单位 
}  
BITMAPFILEHEADER; 

3.  
位图信息头 

BMP位图信息头数据用于说明位图的尺寸等信息。 
typedef   struct
  tagBITMAPINFOHEADER{ 
DWORD   biSize;   //  
本结构所占用字节数 
LONGbiWidth;   //  
位图的宽度,以像素为单位 
LONGbiHeight;   //   位图的高度,以像素为单位 
WORD
  biPlanes;   //   目标设备的级别,必须为1 
WORD   biBitCount//
  每个像素所需的位数,必须是1(双色), 
//  
4(16色),8(256色)或24(真彩色)之一 
DWORD   biCompression;   //  
位图压缩类型,必须是   0(不压缩), 
//  
1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 
DWORD   biSizeImage;   //
  位图的大小,以字节为单位 
LONGbiXPelsPerMeter;   //  
位图水平分辨率,每米像素数 
LONGbiYPelsPerMeter;   //  
位图垂直分辨率,每米像素数 
DWORD   biClrUsed;//  
位图实际使用的颜色表中的颜色数 
DWORD   biClrImportant;//  
位图显示过程中重要的颜色数 
}   BITMAPINFOHEADER; 

4.  
颜色表 

  颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: 
typedef
  struct   tagRGBQUAD   { 
BYTErgbBlue;//  
蓝色的亮度(值范围为0-255) 
BYTErgbGreen;   //  
绿色的亮度(值范围为0-255) 
BYTErgbRed;   //  
红色的亮度(值范围为0-255) 
BYTErgbReserved;//   保留,必须为0 
}  
RGBQUAD; 
颜色表中RGBQUAD结构数据的个数有biBitCount来确定: 
当biBitCount=1,4,8时,分别有2,16,256个表项; 
当biBitCount=24时,没有颜色表项。 
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 
typedef
  struct   tagBITMAPINFO   { 
BITMAPINFOHEADER  
bmiHeader;   //   位图信息头 
RGBQUAD   bmiColors[1];  
//   颜色表 
}   BITMAPINFO; 

5.  
位图数据 
  位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数: 
当biBitCount=1时,8个像素占1个字节; 
当biBitCount=4时,2个像素占1个字节; 
当biBitCount=8时,1个像素占1个字节; 
当biBitCount=24时,1个像素占3个字节; 
Windows规定一个扫描行所占的字节数必须是 
4的倍数(即以long为单位),不足的以0填充, 
一个扫描行所占的字节数计算方法: 
DataSizePerLine=
  (biWidth*   biBitCount+31)/8;   
//  
一个扫描行所占的字节数 
DataSizePerLine=   DataSizePerLine/4*4;   //
  字节数必须是4的倍数 
位图数据的大小(不压缩情况下): 
DataSize=  
DataSizePerLine*   biHeight;

C语言编写的bmp读写程序,码迷,mamicode.com

时间: 2024-10-29 19:08:51

C语言编写的bmp读写程序的相关文章

C语言编写一个&#39;*&#39;金字塔的程序

olj3xg踩系凭珊氏菲<http://weibo.com/LXzpRp/230927982968498303012864> 8e8pxe栏胸俾侔善胶<http://weibo.com/20180414pp/230927983255722881978368> e46952阉友河痹敲呕<http://weibo.com/keMXfnmp/230927983173935224852480> 8fpln0计孪甘摆谱匕<http://weibo.com/20180414p

使用go语言编写IOS和Android程序

go语言目前已可以用来开发android和ios手机app.相关资料: 1.IOS https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!topic/golang-china/zEh_pdSLHDs 需要能访问google 源码:https://bitbucket.org/minux/goios 其它文档: https://medium.com/using-go-in-mobile-apps 2.Android

编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本]

编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本] 1. 开发环境 Jdk 1.7.0_72 Maven 3.2.1 Scala 2.10.6 Spark 1.6.2 Hadoop 2.6.4 IntelliJ IDEA 2016.1.1 2. 创建项目1) 新建Maven项目 2) 在pom文件中导入依赖pom.xml文件内容如下: <?xml version="1.0" encoding="UTF-8"?> &l

【ZZ】C 语言中的指针和内存泄漏 &amp; 编写高效的C程序与C代码优化

C 语言中的指针和内存泄漏 http://www.ibm.com/developerworks/cn/aix/library/au-toughgame/ 编写高效的C程序与C代码优化 http://www.cnblogs.com/archimedes/p/writing-efficient-c-and-code-optimization.html

C语言编写cgi程序(上)

cgi简介: 公共网关接口CGI(Common Gateway Interface) 是WWW技术中最重要的技术之一,有着不可替代的重要地位.CGI是外部应用程序(CGI程序)与Web服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的规程.CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体.(百度介绍) CGI可以用任何语言编写,使用C语言编写CGI,可以提高系统的效率. 未完待续...

C语言编写cgi程序(下)

在<<C语言写cgi程序(上)>>中,我们大概知道了cgi的工作原理.今天我们看看c语言写的cgi,是怎么来处理数据的.  c语言中,通过getenv("环境变量")函数来获取页面传送给cgi的数据,一般通过printf()返回给页面一些数据. 其中C语言中的环境变量包括: HTTP-REFERER:调用该CGI程序的网页的URL.  REMOTE-HOST:调用该CGI程序的Web浏览器的机器名和域名.  REQUEST- METHOD:指的是当Web服务器传

swift语言 编写 ios开发 第一个程序hello world!

老实说:第一个swift语句的ios不是代码敲出来的,我甚至还没来得急看代码,hello world 就出来了..... 本人开发环境:mac osx 10.10 dp1 + xcode6 beta + swift(更低xcode不支持swift语言) 思路与大致过程: 1.建立工程,工程包含界面文件,代码文件等等 2.在工程的界面文件中加入text控件,用于显示hello world 3.输入hello world ,模拟运行 让我们一步一步来: 1.建立工程,工程包含界面文件,代码文件等等

编写优质嵌入式C程序(转)

前言:这是一年前我为公司内部写的一个文档,旨在向年轻的嵌入式软件工程师们介绍如何在裸机环境下编写优质嵌入式C程序.感觉是有一定的参考价值,所以拿出来分享,抛砖引玉. 转载请注明出处:http://blog.csdn.net/zhzht19861011/article/details/45508029 摘要:本文首先分析了C语言的陷阱和缺陷,对容易犯错的地方进行归纳整理:分析了编译器语义检查的不足之处并给出防范措施,以Keil MDK编译器为例,介绍了该编译器的特性.对未定义行为的处理以及一些高级

c语言编写经验逐步积累3

寥寥数笔,记录我的C语言盲点笔记,只为曾经经历过,亦有误,可交流. 1.typedef来定义一个函数指针类型的方法,定义一个新的函数指针类型. :建立一个类型别名的方法很简单,在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头". typedef int (*PFUN)(): 定义PFUN这个函数指针类型,由编译器自动来完成,比如PFUN pfun;定义了一个函数指针,类似于抽象出一种新的变量类型. typedef unsigned short (*pTask