主要介绍下与设备无关的位图DIB(Device Independent Bitmap)
位图的基本格式
1.文件头
typedef struct tagBITMAPFILEHEADER {
WORD bfType;//bmp图类型为'BM'或者0X4D42
DWORD bfSize;//整个文件大小
WORD bfReserved1;//0
WORD bfReserved2;//0
DWORD bfOffBits;//DIB像素数据偏移
} BITMAPFILEHEADER
2.信息头
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;//结构体大小 = 40
LONG biWidth;//文件宽度(像素)
LONG biHeight;//文件高度(像素)
WORD biPlanes;//1
WORD biBitCount;//每像素位数(1,4,8,16,24,32)
DWORD biCompression;//压缩方式
DWORD biSizeImage;//实际位图数据占用的字节数
LONG biXPelsPerMeter;//X方向分辨率
LONG biYPelsPerMeter;//Y方向分辨率
DWORD biClrUsed;//使用的颜色数
DWORD biClrImportant;//重要颜色数
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
biBitCount字段
$ 1(2色DIB)
$ 4(16色DIB)
$ 8(256色DIB)
$ 24(全色DIB)
3.RGB色彩表(不一定有)
对于像素位(biBitCount字段)是1,4,和8时,BITMAPINFOHEADER后面跟着的是色彩表。
typedef struct tagRGBQUAD {
BYTE rgbBlue;//蓝色
BYTE rgbGreen;//绿色
BYTE rgbRed;//红色
BYTE rgbReserved;//保留,0
} RGBQUAD;
每个像素点都是一个RGB,三种色彩组成颜色。要注意的就是里面的元素顺序是BGR。
4.位图像素位
这里才是图像数据的真实存放处,可以在这里读取图像的数据进行操作。每个像素点都是由RGB数组构成。要注意的是,在DIB中,图像的底行是文件的第一行,图像的顶行是文件的最后一行。但是对于同一行来说,还是从左到右存放数据的。windows程序设计上是这样说的:从下到上DIB的原点是位图图像的左下角,它是图像的第一行的第一个像素。从上到下DIB的原点也是位图图像的左下角,但是这种情况下,左下角是位图数据的最后一行的第一个像素。
DIB中的行数是BITMAPINFOHEADER结构中的biHeight字段,每一行的像素是该结构中biWidth字段,每一行从左边开始,向右数,每个像素位数由bcBitCount确定。
每行的长度必须是4的倍数。
RowLength = 4 * ((bmch.bcWidth * bmch.bcBitCount + 31) / 32)计算;
总的像素位数据大小 = RowLength *bmch.biHeight计算。
下面是对DIB文件的读写:
/****************************************************************************
*函数名称: ReadBmp()
*函数参数: const char *bmpName 写入bmp格式文件的名称及路径
***************************************************************************/
bool ReadBmp(const char *strFile)
{
BITMAPFILEHEADER bitHead;
BITMAPINFOHEADER bitInfoHead;
FILE* pfile;
pfile = fopen(strFile,"rb");//打开文件
if(pfile!=NULL)
{
printf("file bkwood.bmp open success.\n");
//读取位图文件头信息
fread(&bitHead,1,sizeof(BITMAPFILEHEADER),pfile);
//fseek(pfile,2,SEEK_CUR); // "BM"
if(bitHead.bfType != 0x4d42)
{
printf("file is not .bmp file!");
return false;
}
//读取位图信息头信息
fread(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),pfile);
}
tagRGBQUAD *pRgb ;
int width = bitInfoHead.biWidth;
int height = bitInfoHead.biHeight;
//分配内存空间把源图存入内存
int l_width = 4 * ((width* bitInfoHead.biBitCount+31) /32);//计算位图的实际宽度并确保它为32的倍数
BYTE *pColorData=(BYTE *)malloc(height*l_width);
memset(pColorData,0,height*l_width);
long nData = height*l_width;
//把位图数据信息读到数组里
fread(pColorData,1,nData,pfile);
fclose(pfile);
return true;
}
/****************************************************************************
*函数名称: saveBmp()
unsigned char *imgBuf 待存盘的位图数据
int width, 以像素为单位待存盘的位图宽
int height, 以像素为单位待存盘的位图高
int biBitCount, 每个像素占的位数
RGBQUAD *pColorTable 颜色表指针
*函数返回值:0为失败 1为成功
*函数描述:给定写入bmp文件的名称和路径 要写入图像的位图数据,宽,高,写进文件中
*
***************************************************************************/
bool saveBmp(const char* bmpName,unsigned char *imgBuf,int width,int height,int biBitCount,RGBQUAD *pColorTable)
{
if(!imgBuf)//imgBuf 待存盘的位图数据
return 0;
int colorTablesize = 0;
if(biBitCount == 8)
colorTablesize =1024;
int lineByte = (width * biBitCount/8+3)/4*4; //行的长度。以字节为单位的每行长度始终是4的倍数
FILE *fp = fopen(bmpName,"wb");
if(fp == 0) return 0;
BITMAPFILEHEADER fileHead; //文件头
fileHead.bfType= 0x4d42; //确保是bmp图像:"BM"
fileHead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + colorTablesize + lineByte *height; //图像大小
fileHead.bfReserved1 = 0;
fileHead.bfReserved2 = 0;
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) //如果是8bits,写入色彩表
fwrite(pColorTable,sizeof(RGBQUAD),256,fp);
fwrite(imgBuf,height * lineByte,1,fp); //写图像的数据内容
fclose(fp);
return 1;
}
分享到:
相关推荐
8.改程序在《windows程序设计》上的一个例子改编而来,并且正在完善该位图类中, 以加入更多丰富的底层操作功能。 改试验程序主要供想研究位图结构的人查看用。 9.windows搞出了4种位图种类,真作孽~~ 另,16、24、...
第15章 系统程序设计 15.1 WindowsCE的内存体系结构 15.1.1 应用程序的地址空间 15.1.2 内核态的地址空间 15.2 编写跨平台的WindowsCE应用程序 15.2.1 平台与操作系统版本 15.2.2 编译时的版本确定 15.2.3 显式链接 ...
第15章 系统程序设计 15.1 WindowsCE的内存体系结构 15.1.1 应用程序的地址空间 15.1.2 内核态的地址空间 15.2 编写跨平台的WindowsCE应用程序 15.2.1 平台与操作系统版本 15.2.2 编译时的版本确定 15.2.3 显式链接 ...
1.3 Windows应用程序设计的特点 1.4 Windows应用程序的开发工具 1.5 面向对象和Windows编程 第二课 使用Visual C++ 5.0 2.1 Visual C++可视化集成开发环境 2.2 创建、组织文件、工程和工作区 2.3 ...
1.3 Windows应用程序设计的特点 1.4 Windows应用程序的开发工具 1.5 面向对象和Windows编程 第二课 使用Visual C++ 5.0 2.1 Visual C++可视化集成开发环境 2.2 创建、组织文件、工程和工作区 2.3 ...
1.3 Windows应用程序设计的特点 1.4 Windows应用程序的开发工具 1.5 面向对象和Windows编程 第二课 使用Visual C++ 5.0 2.1 Visual C++可视化集成开发环境 2.2 创建、组织文件、工程和工作区 2.3 ...
2.3.2 Windows消息和事件驱动 40 2.3.3 常用消息 41 2.3.4 MFC的消息映射 42 2.4 消息与事件响应 44 2.4.1 添加类 44 2.4.2 添加类成员 45 2.4.3 添加消息响应 46 2.4.4 添加事件 47 2.4.5 添加函数重写 48 2.4.6 ...
Screen.zip 一个基于DirectX的截图示例,又是MMX的新作^o^,你看懂了话都能截图了(14KB)<END><br>22,opengl1.zip OpenGL三维图形程序设计(539kb)<END><br>23,wingrap.zip Windows图形编程(189kb)<END><br>24...
具有相关文档,可以执行从设计到工程的所有操作的多功能性 易于使用,快速,专业且功能强大的产品 ABViewer Enterprise 14 最重要的方面是质量,速度和价格! ABViewer Enterprise 14 支持的格式: AutoCAD DWG,...
|------ 1.3 利用Visual C++/MFC开发Windows程序的优势 |------ 1.4 利用MFC进行开发的通用方法介绍 |------ 1.5 MFC中常用类,宏,函数介绍 +-- 第二章 图形输出 |------ 2.1 和GUI有关的各种对象 |------ 2.2 在...
(29KB)<END><br>50,DirTree.zip 这个派生的TreeCtrl类使你能够在自己的程序中方便地加入浏览目录、文件的功能,就像Windows Explore一样。缺陷:重画时有闪烁。总的说来不错。(42KB)<END><br>51,CTreeList.zip ...