C语言编写的bmp读写程序
C语言编写的bmp读写程序 建议先把bmp的数据存储格式了解下
- <span style="font-size:16px;">#include "Windows.h"
- #include "stdio.h"
- #include "string.h"
- #include "malloc.h"
- unsigned char *pBmpBuf;//读入图像数据的指针
- int bmpWidth;//图像的宽
- int bmpHeight;//图像的高
- RGBQUAD *pColorTable;//颜色表指针
- int biBitCount;//图像类型,每像素位数
- bool readBmp(char *bmpName)
- {
- //二进制读方式打开指定的图像文件
- FILE *fp=fopen(bmpName,"rb");
- if(fp==0) return 0;
- //跳过位图文件头结构BITMAPFILEHEADER
- fseek(fp, sizeof(BITMAPFILEHEADER),0);
- //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
- BITMAPINFOHEADER head;
- fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);
- //获取图像宽、高、每像素所占位数等信息
- bmpWidth = head.biWidth;
- bmpHeight = head.biHeight;
- biBitCount = head.biBitCount;
- //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
- int lineByte=(bmpWidth * biBitCount/8+3)/4*4;
- //灰度图像有颜色表,且颜色表表项为256
- if(biBitCount==8){
- //申请颜色表所需要的空间,读颜色表进内存
- pColorTable=new RGBQUAD[256];
- fread(pColorTable,sizeof(RGBQUAD),256,fp);
- }
- //申请位图数据所需要的空间,读位图数据进内存
- pBmpBuf=new unsigned char[lineByte * bmpHeight];
- fread(pBmpBuf,1,lineByte * bmpHeight,fp);
- //关闭文件
- fclose(fp);
- return 1;
- }
- bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height,
- int biBitCount, RGBQUAD *pColorTable)
- {
- //如果位图数据指针为0,则没有数据传入,函数返回
- if(!imgBuf)
- return 0;
- //颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0
- int colorTablesize=0;
- if(biBitCount==8)
- colorTablesize=1024;
- //待存储图像数据每行字节数为4的倍数
- int lineByte=(width * biBitCount/8+3)/4*4;
- //以二进制写的方式打开文件
- FILE *fp=fopen(bmpName,"wb");
- if(fp==0) return 0;
- //申请位图文件头结构变量,填写文件头信息
- BITMAPFILEHEADER fileHead;
- fileHead.bfType = 0x4D42;//bmp类型
- //bfSize是图像文件4个组成部分之和
- fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
- + colorTablesize + lineByte*height;
- fileHead.bfReserved1 = 0;
- fileHead.bfReserved2 = 0;
- //bfOffBits是图像文件前3个部分所需空间之和
- fileHead.bfOffBits=54+colorTablesize;
- //写文件头进文件
- fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);
- //申请位图信息头结构变量,填写信息头信息
- BITMAPINFOHEADER head;
- head.biBitCount=biBitCount;
- head.biClrImportant=0;
- head.biClrUsed=0;
- head.biCompression=0;
- head.biHeight=height;
- head.biPlanes=1;
- head.biSize=40;
- head.biSizeImage=lineByte*height;
- head.biWidth=width;
- head.biXPelsPerMeter=0;
- head.biYPelsPerMeter=0;
- //写位图信息头进内存
- fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);
- //如果灰度图像,有颜色表,写入文件
- if(biBitCount==8)
- fwrite(pColorTable, sizeof(RGBQUAD),256, fp);
- //写位图数据进文件
- fwrite(imgBuf, height*lineByte, 1, fp);
- //关闭文件
- fclose(fp);
- return 1;
- }
- void main()
- {
- char inFileName[90],outFileName[90];
- printf("请输入原始位图文件的文件名:");
- scanf("%s",inFileName);
- printf("请输入加密程序产生的新位图文件的文件名:");
- scanf("%s",outFileName);
- //读入指定BMP文件进内存
- readBmp(inFileName);
- //输出图像的信息
- printf("width=%d,height=%d, biBitCount=%d\n",bmpWidth,bmpHeight, biBitCount);
- //将图像数据存盘
- saveBmp(outFileName, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable);
- //清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间
- delete []pBmpBuf;
- if(biBitCount==8)
- delete []pColorTable;
- }
- </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读写程序的更多相关文章
- c语言编写51单片机中断程序,执行过程是怎样的?
Q:c语言编写51单片机中断程序,执行过程是怎样的? 例如程序:#include<reg52.h> void main(void) { EA=1; //开放总中断 E ...
- 使用go语言编写IOS和Android程序
go语言目前已可以用来开发android和ios手机app.相关资料: 1.IOS https://groups.google.com/forum/?utm_medium=email&utm_ ...
- 编写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 ...
- 近50种语言编写的“Hello, World”,你会几种?可不要贪杯哦~
本文转自公众号CSDN(ID:CSDNnews)作者:Sylvain Saurel,译者:风车云马
- 基于php基础语言编写的小程序之计算器
基于php基础语言编写的小程序之计算器 需求:在输入框中输入数字进行加.减.乘.除运算(html+php) 思路: 1首先要创建输入数字和运算符的输入框,数字用input的text属性,运算符用sel ...
- 【ZZ】C 语言中的指针和内存泄漏 & 编写高效的C程序与C代码优化
C 语言中的指针和内存泄漏 http://www.ibm.com/developerworks/cn/aix/library/au-toughgame/ 本文讨论了几种在使用动态内存分配时可以避免的陷 ...
- 用C语言编写一个简单的词法分析程序
问题描述: 用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表.如果产生词法错误,则显示错误信息.位置,并试图从错误中恢复.简单的恢复方法 ...
- [转载] 使用C/C++语言编写基于DSP程序的注意事项
原文地址:『转』使用C/C++语言编写基于DSP程序的注意事项作者:skysmile 1.不影响执行速度的情况下,可以使用c或c/c++语言提供的函数库,也可以自己设计函数,这样更易于使用“裁缝师 ...
- 编写优质嵌入式C程序
前言:这是一年前我为公司内部写的一个文档,旨在向年轻的嵌入式软件工程师们介绍如何在裸机环境下编写优质嵌入式C程序.感觉是有一定的参考价值,所以拿出来分享,抛砖引玉. 转载请注明出处:http://bl ...
随机推荐
- 刘德华夏日Fiesta演唱会上那个表演探戈舞的演员是谁啊?_百度知道
刘德华夏日Fiesta演唱会上那个表演探戈舞的演员是谁啊?_百度知道 刘德华夏日Fiesta演唱会上那个表演探戈舞的演员是谁啊? 2008-05-28 00:04 topofhill | ...
- 解决java mail发送TXT附件被直接显示在正文中的问题
这两天遇到一个问题,关于使用java mail发送邮件的问题. 详细是这样子的:我使用java mail发送异常报告邮件,邮件中有一个包含异常日志的附件,和关于设备信息的邮件正文.假设日志为log后缀 ...
- Swift初体验 (一)
// 声明一个常量 let maxNumberOfStudents: Int = 47 // 声明一个变量,假设没有在声明的时候初始化,须要显示的标注其类型 var currentNumberOfSt ...
- 我是小白之<%%>用法
下面知识都是摘录自网络 <%= %>输出,等价于Response.Write()<%%> 写代码<%-- --%>注释. <% %>跟其它serv ...
- 恢复PasswordChar 默认值、取消密码框设置
//三种都是清空 this.textBox1.PasswordChar = new char(); this.textBox1.PasswordChar = '\0'; this.textBox1.P ...
- Cocos2d-x 手游聊天系统需求分析
手游聊天系统需求分析 转载请注明:IT_xiao小巫 移动开发狂热者群:299402133 策划需求图 參考系统:刀塔传奇 点击这个.然后弹出以下的对话框 游戏类型:卡牌 分析:刀塔传奇聊天系统分为3 ...
- Swift - 使用TableView的静态单元格进行页面布局
通过使用静态单元格的列表,我们可以很方便的进行页面布局.下面通过一个“添加任务页面”来进行演示. 效果图如下: 实现步骤: 1,在storyboard中拖入一个TableViewController, ...
- TEXT文本编辑框4 点击按钮读取文本框内容到内表
*&---------------------------------------------------------------------* *& Report ZTEST_CWB ...
- Spring Boot——开发新一代Spring应用
Spring官方网站本身使用Spring框架开发,随着功能以及业务逻辑的日益复杂,应用伴随着大量的XML配置文件以及复杂的Bean依赖关系.随着Spring 3.0的发布,Spring IO团队逐渐开 ...
- C中的几组指针
1.二维数组 下面就三种二维数组进行说明. 1: int **Ptr; 2: int *Ptr[ 5 ]; 3: int ( *Ptr )[ 5 ]; 以上三例都是整数的二维数组,都可以用形如 Ptr ...