C语言编写的bmp读写程序

简介: C语言编写的bmp读写程序 建议先把bmp的数据存储格式了解下  [cpp] view plaincopy   #include "Windows.h"   #include "stdio.

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

[cpp]  view plain copy
 
  1. <span style="font-size:16px;">#include "Windows.h"  
  2. #include "stdio.h"  
  3. #include "string.h"  
  4. #include "malloc.h"  
  5.   
  6. unsigned char *pBmpBuf;//读入图像数据的指针  
  7. int bmpWidth;//图像的宽  
  8. int bmpHeight;//图像的高  
  9. RGBQUAD *pColorTable;//颜色表指针  
  10. int biBitCount;//图像类型,每像素位数  
  11.   
  12. bool readBmp(char *bmpName)  
  13. {  
  14.   //二进制读方式打开指定的图像文件  
  15.   FILE *fp=fopen(bmpName,"rb");  
  16.   if(fp==0) return 0;  
  17.       
  18.       
  19.   //跳过位图文件头结构BITMAPFILEHEADER  
  20.   fseek(fp, sizeof(BITMAPFILEHEADER),0);  
  21.   //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中  
  22.   BITMAPINFOHEADER head;     
  23.   fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);    
  24.   //获取图像宽、高、每像素所占位数等信息  
  25.   bmpWidth = head.biWidth;  
  26.   bmpHeight = head.biHeight;  
  27.   biBitCount = head.biBitCount;  
  28.   //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)  
  29.   int lineByte=(bmpWidth * biBitCount/8+3)/4*4;  
  30.   //灰度图像有颜色表,且颜色表表项为256  
  31.   if(biBitCount==8){  
  32.   //申请颜色表所需要的空间,读颜色表进内存  
  33.   pColorTable=new RGBQUAD[256];  
  34.   fread(pColorTable,sizeof(RGBQUAD),256,fp);  
  35.   }  
  36.   //申请位图数据所需要的空间,读位图数据进内存  
  37.   pBmpBuf=new unsigned char[lineByte * bmpHeight];  
  38.   fread(pBmpBuf,1,lineByte * bmpHeight,fp);  
  39.   //关闭文件  
  40.   fclose(fp);  
  41.   return 1;  
  42. }  
  43.   
  44. bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height,    
  45.   int biBitCount, RGBQUAD *pColorTable)  
  46. {  
  47.   //如果位图数据指针为0,则没有数据传入,函数返回  
  48.   if(!imgBuf)  
  49.   return 0;  
  50.   //颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0  
  51.   int colorTablesize=0;  
  52.   if(biBitCount==8)  
  53.   colorTablesize=1024;  
  54.   //待存储图像数据每行字节数为4的倍数  
  55.   int lineByte=(width * biBitCount/8+3)/4*4;  
  56.   //以二进制写的方式打开文件  
  57.   FILE *fp=fopen(bmpName,"wb");  
  58.   if(fp==0) return 0;  
  59.   //申请位图文件头结构变量,填写文件头信息  
  60.   BITMAPFILEHEADER fileHead;  
  61.   fileHead.bfType = 0x4D42;//bmp类型  
  62.   //bfSize是图像文件4个组成部分之和  
  63.   fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)  
  64.   + colorTablesize + lineByte*height;  
  65.   fileHead.bfReserved1 = 0;  
  66.   fileHead.bfReserved2 = 0;  
  67.   //bfOffBits是图像文件前3个部分所需空间之和  
  68.   fileHead.bfOffBits=54+colorTablesize;  
  69.   //写文件头进文件  
  70.   fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);  
  71.   //申请位图信息头结构变量,填写信息头信息  
  72.   BITMAPINFOHEADER head;    
  73.   head.biBitCount=biBitCount;  
  74.   head.biClrImportant=0;  
  75.   head.biClrUsed=0;  
  76.   head.biCompression=0;  
  77.   head.biHeight=height;  
  78.   head.biPlanes=1;  
  79.   head.biSize=40;  
  80.   head.biSizeImage=lineByte*height;  
  81.   head.biWidth=width;  
  82.   head.biXPelsPerMeter=0;  
  83.   head.biYPelsPerMeter=0;  
  84.   //写位图信息头进内存  
  85.   fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);  
  86.   //如果灰度图像,有颜色表,写入文件    
  87.   if(biBitCount==8)  
  88.   fwrite(pColorTable, sizeof(RGBQUAD),256, fp);  
  89.   //写位图数据进文件  
  90.   fwrite(imgBuf, height*lineByte, 1, fp);  
  91.   //关闭文件  
  92.   fclose(fp);  
  93.   return 1;  
  94. }  
  95.   
  96. void main()  
  97. {  
  98.   char inFileName[90],outFileName[90];  
  99. printf("请输入原始位图文件的文件名:");  
  100.   scanf("%s",inFileName);  
  101.   printf("请输入加密程序产生的新位图文件的文件名:");  
  102.   scanf("%s",outFileName);  
  103. //读入指定BMP文件进内存  
  104.   readBmp(inFileName);  
  105.   //输出图像的信息  
  106.   printf("width=%d,height=%d, biBitCount=%d\n",bmpWidth,bmpHeight, biBitCount);  
  107.   //将图像数据存盘  
  108.   saveBmp(outFileName, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable);  
  109.   //清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间  
  110.   delete []pBmpBuf;  
  111.   if(biBitCount==8)  
  112.   delete []pColorTable;  
  113. }  
  114. </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; 

目录
相关文章
|
11月前
|
存储 自然语言处理 编译器
【C语言】编译与链接:深入理解程序构建过程
【C语言】编译与链接:深入理解程序构建过程
177 1
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
238 1
|
NoSQL 编译器 程序员
【C语言】揭秘GCC:从平凡到卓越的编译艺术,一场代码与效率的激情碰撞,探索那些不为人知的秘密武器,让你的程序瞬间提速百倍!
【8月更文挑战第20天】GCC,GNU Compiler Collection,是GNU项目中的开源编译器集合,支持C、C++等多种语言。作为C语言程序员的重要工具,GCC具备跨平台性、高度可配置性及丰富的优化选项等特点。通过简单示例,如编译“Hello, GCC!”程序 (`gcc -o hello hello.c`),展示了GCC的基础用法及不同优化级别(`-O0`, `-O1`, `-O3`)对性能的影响。GCC还支持生成调试信息(`-g`),便于使用GDB等工具进行调试。尽管有如Microsoft Visual C++、Clang等竞品,GCC仍因其灵活性和强大的功能被广泛采用。
311 1
|
编译器 C语言 计算机视觉
C语言实现的图像处理程序
C语言实现的图像处理程序
|
10月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
264 5
|
10月前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
268 4
|
10月前
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
223 2
|
10月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
245 1
|
10月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
196 1
|
存储 编译器 程序员
C语言程序的基本结构
C语言程序的基本结构包括:1)预处理指令,如 `#include` 和 `#define`;2)主函数 `main()`,程序从这里开始执行;3)函数声明与定义,执行特定任务的代码块;4)变量声明与初始化,用于存储数据;5)语句和表达式,构成程序基本执行单位;6)注释,解释代码功能。示例代码展示了这些组成部分的应用。
522 10