搜档网
当前位置:搜档网 › 256级灰度BMP文件读写的源代码+c语言图像处理

256级灰度BMP文件读写的源代码+c语言图像处理

256级灰度BMP文件读写的源代码+c语言图像处理
256级灰度BMP文件读写的源代码+c语言图像处理

本文档最早发布于 https://www.sodocs.net/doc/281182809.html,/u/1495182054

1.256级灰度BMP文件读写的源代码!

首先要明白256级灰度BMP文件的格式

1.首先是一个14个字节的文件头,定义如下

typedef struct tagBITMAPFILEHEADER{

WORD bfType;

DWORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

bfType是表明BMP文件类型的数据,在这里我们填入的是0x4d42,其实就是BM两个字,bfSize是文件大小,bfOffBits是文件头到数据块的偏移量,对于256级灰度图,就是1078个字节,后面会做描述

2.接下来是40个字节的是描述位图属性的40个字节

typedef struct tagBITMAPINFOHEADER{

DWORD biSize;

LONG biWidth;

LONG biHeight;

WORD biPlanes;

WORD biBitCount;

DWORD biCompression;

DWORD biSizeImage;

LONG biXPelsPerMeter;

LONG biYPelsPerMeter;

DWORD biClrUsed;

DWORD biClrImportant;

} BITMAPINFOHEADER, *PBITMAPINFOHEADER;

这里面只有biWidth表示宽度,biPlanes表示高度,biBitCount对于256级灰度正好是8

3.由于是256级灰度图,那么有256个调色板数据,每个调色板是如下定义的

typedef struct tagRGBQUAD {

BYTE rgbBlue;

BYTE rgbGreen;

BYTE rgbRed;

BYTE rgbReserved;

}RGBQUAD, *PRGBQUAD;

调色板数据其实告诉了显示器实际显示的时候的具体颜色,所以调色板长度是1024字节4.最后是按行组织的图像数据,但这些数据并不是简单的按照图像的高度宽度w*h的数组数据这些数据最重要的特点是

a.按行组织,每行宽度是w,但是要进行4个字节的对齐。比如如果是图像宽度是253,那么数据对齐后一行还是有256个字节。对齐可以用下面的宏来计算

#define GET_ALIGN(x) (((x+3)/4)*4)

b.图像数据是倒行的,也就是数据第一行对应图像最后一行,最后一行数据对应第一行

图像的实际数据之前的偏移量是:

sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)=14+40+102 4=1078个字节。

下面是实际的BMP文件输入输出函数代码:

/*********************************************/

从文件读入内存代码:

pw返回宽度;

ph返回高度;

函数返回内存指针;

/*********************************************/

unsigned char* read_bmp(const char* pszFileName, int* pw, int* ph)

{

BITMAPFILEHEADER bfh;

BITMAPINFOHEADER bmh;

FILE *fp;

unsigned char* pImg = NULL;

int i;

fp=fopen(pszFileName, "rb");//二进制打开

if(fp==NULL) return NULL;

fread(&bfh, sizeof(BITMAPFILEHEADER),1, fp);

fread(&bmh, sizeof(BITMAPINFOHEADER),1, fp);

//判断是否8bit的图像

if(bfh.bfType!=0x4d42 && bmh.biBitCount!=8) return NULL;

pImg=(unsigned char*)malloc(bmh.biWidth*bmh.biHeight);//开辟空间

*pw=bmh.biWidth;

*ph=bmh.biHeight;

for(i=0; i

{

fseek(fp, 1078+(bmh.biHeight-i-1)*GET_ALIGN(bmh.biWidth), SEEK_SET);

fread(pImg+i*bmh.biWidth, 1, bmh.biWidth, fp);

}

fclose(fp);

return pImg;

}

/*********************************************/

bmp文件输出:将数据从*pImg存入* pszFileName指向的文件中

w指定宽度,h指定高度。

/*********************************************/

void write_bmp(const char* pszFileName, unsigned char* pImg, int w, int h) {

BITMAPFILEHEADER bfh;

BITMAPINFOHEADER bmh;

RGBQUAD bmiColors[256];

FILE* fp;

int i;

fp=fopen(pszFileName, "wb");

if(fp==NULL) return;

//写位图文件头

bfh.bfType = 0x4d42;

bfh.bfSize = GET_ALIGN(w)*h+1078;

bfh.bfOffBits = 1078;

bfh.bfReserved1=0;

bfh.bfReserved2=0;

//设置位图参数

bmh.biSize = 40;

bmh.biWidth = w;

bmh.biHeight = h;

bmh.biPlanes = 1;

bmh.biBitCount= 8;

bmh.biCompression = 0;

bmh.biSizeImage = GET_ALIGN(w)*h;

bmh.biXPelsPerMeter = 0;

bmh.biYPelsPerMeter = 0;

bmh.biClrUsed = 0;

bmh.biClrImportant = 0;

//创建256个灰度调色板

for(i=0; i<256; i++)

{

bmiColors[i].rgbRed = (BYTE)i;

bmiColors[i].rgbGreen = (BYTE)i;

bmiColors[i].rgbBlue = (BYTE)i;

}

fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fp);//bfh指向被写入的数据,fp指向被改写的文件

fwrite(&bmh, sizeof(BITMAPINFOHEADER), 1, fp);

fwrite(bmiColors, sizeof(RGBQUAD), 256, fp); //调色板写入文件

//行倒过来,对齐后写入

for(i=0; i

{

fwrite(pImg+(h-i-1)*w, 1, GET_ALIGN(w), fp); }

fclose(fp);

}

这是一个用于测试的指纹图

2.对图像进行反色,理解调色板

介绍了BMP格式,里面有一个这么一段,是设置灰度线性调色板

for(i=0; i<256; i++)

{

bmiColors[i].rgbRed = (BYTE)i;

bmiColors[i].rgbGreen = (BYTE)i;

bmiColors[i].rgbBlue = (BYTE)i;

}

这段代码的作用是设置BMP文件中的调色板,意思是图像像素值为i的,实际显示的时候正好是RGB(i,i,i),这正好是个线性的灰阶。RGB(0,0,0)是纯黑色,RGB(255,255,255)是白色。大家可以打开Window附件/画图工具来看一下,选择菜单颜色/编辑颜色,在对话框中选择规定自定义颜色,就可以输入RGB的数值来看实际的颜色效果了。

所以,如果我们需要反色的话,其实我们只需要简单的把这个调色板反过来就可以了,也就是

for(i=0; i<256; i++)

{

bmiColors[i].rgbRed = (BYTE)(255-i);

bmiColors[i].rgbGreen = (BYTE)(255-i);

bmiColors[i].rgbBlue = (BYTE)(255-i);

}

当然我们也可以不改变调色板,把后面真正的像素值取反就可以了,也就是文件头1078字节后

for(i=0; i

很简单的吧,这两种反色最后看到的效果相同,但含义是不一样的。

3 .做一个自己的截图软件

有了前面两节的基础,我们就可以做一个简单的截图软件了。

下面这个函数cut可以按照把(x0,y0),(x1,y1)两个点组成的对角线矩形区域的图像截取出来

输入参数pImg, 输出参数pImg2, w, h是pImg的图像的高度和宽度

输入的时候要求x0

int cut(unsigned char *pImg, unsigned char *pImg2, int x0, int y0, int x1, int y1, int w, int h)

{

int i, j, cnt=0;

if(x0<0 || x0>w-1 || y0<0 || y0>h-1) return -1;

for(i=y0; i

for(j=x0; j

}

这样输出的图像就是宽度为(x1-x0),高度为(y1-y0)的图像了。

可以用下面的代码测试一下

int step3(void)

{

int w, h;

unsigned char *pImg, *pImg2;

printf("step3: test cut image!\n");

pImg= read_bmp("test.bmp", &w, &h);

if(pImg==NULL) return -1;

pImg2=(unsigned char*)malloc(100*100);

cut(pImg, pImg2, 10,10,110,110, w, h);

write_bmp("cut.bmp", pImg2, 100, 100);

free(pImg);

free(pImg2);

return 1;

}

这样就把一个位置于原图像(10,10)-(110,110),大小为100x100的图像截取出来了。并且保存到了cut.bmp中

4.保留一点颜色,理解调色板

其实在第二节我们已经介绍了调色板,在那里我们将图像进行了反色,我们采用的其中一种方法是把调色板

进行反色。

在这里我们介绍一下如何在调色板里保留一些颜色,这样我们可以在图像上画图,有利于显示。

先介绍我们这一期的画图函数

/**************************************************/

描绘细节点函数(细节点是指纹中的一个概念,在后续文章中会介绍)

,这个函数可以指定一个坐标位置x,y,把图像上这个点的附近画一个小圆圈。

像素值是1。

/**************************************************/

void paint_min(unsigned char *pImg, int x, int y, int w, int h)

{

if(x<2 || y<2 || x>w-3 || y>h-3) return;

pImg[(y-1)*w+x-2]=1;

pImg[ y *w+x-2]=1;

pImg[(y+1)*w+x-2]=1;

pImg[(y+2)*w+x-1]=1;

pImg[(y+2)*w+ x ]=1;

pImg[(y+2)*w+x+1]=1;

pImg[(y+1)*w+x+2]=1;

pImg[ y *w+x+2]=1;

pImg[(y-1)*w+x+2]=1;

pImg[(y-2)*w+x+1]=1;

pImg[(y-2)*w+ x ]=1;

pImg[(y-2)*w+x-1]=1;

}

/**************************************************/

画矩形函数,这个函数描绘了一个像素值为color的函数

矩形宽度为x0到x1,高度为y0到y1;*pImg指向位图数据区。

/**************************************************/

void draw_rect(unsigned char *pImg, int x0, int y0, int x1, int y1, int w, int h, int color)

{

int i, j;

if(x0<0 || x1>w-1 || y0<0 || y1>h-1) return;

for(i=y0; i

{

pImg[i*w+x0]=color;

pImg[i*w+x1]=color;

}

for(j=x0; j

{

pImg[y0*w+j]=color;

pImg[y1*w+j]=color;

}

}

/**************************************************/

接下来是另外一个保存图像的函数,这里我们改变了调色板1,2,3,

分别保留为红颜色,绿颜色,蓝颜色

/**************************************************/

void write_color_bmp(const char* pszFileName,unsigned char* pImg,int w,int h) {

BITMAPFILEHEADER bfh;

BITMAPINFOHEADER bmh;

RGBQUAD bmiColors[256];

FILE* fp;

int i;

fp=fopen(pszFileName, "wb");

if(fp==NULL) return;

//写位图文件头

bfh.bfType = 0x4d42;

bfh.bfSize = GET_ALIGN(w)*h+1078;

bfh.bfOffBits = 1078;

bfh.bfReserved1 =0;

bfh.bfReserved2 = 0;

//设置位图参数

bmh.biSize = 40;

bmh.biWidth = w;

bmh.biHeight = h;

bmh.biPlanes = 1;

bmh.biBitCount = 8;

bmh.biCompression = 0;

bmh.biSizeImage = GET_ALIGN(w)*h;

bmh.biXPelsPerMeter = 0;

bmh.biYPelsPerMeter = 0;

bmh.biClrUsed = 0;

bmh.biClrImportant = 0;

//创建256个灰度调色板

for(i=0; i<256; i++)

{

bmiColors[i].rgbRed = (BYTE)i;

bmiColors[i].rgbGreen = (BYTE)i;

bmiColors[i].rgbBlue = (BYTE)i;

}

//调色板1为红颜色

bmiColors[1].rgbRed = 255;

bmiColors[1].rgbGreen = 0;

bmiColors[1].rgbBlue = 0;

//调色板2为绿颜色

bmiColors[2].rgbRed = 0;

bmiColors[2].rgbGreen = 255;

bmiColors[2].rgbBlue = 0;

//调色板3为蓝颜色

bmiColors[3].rgbRed = 0;

bmiColors[3].rgbGreen = 0;

bmiColors[3].rgbBlue = 255;

fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fp);

fwrite(&bmh, sizeof(BITMAPINFOHEADER), 1, fp);

fwrite(bmiColors, sizeof(RGBQUAD), 256, fp); //行倒过来,对齐后写入

for(i=0; i

{

fwrite(pImg+(h-i-1)*w, 1, GET_ALIGN(w), fp);

}

fclose(fp);

}

接下来是我们的测试代码,注意我们要画颜色的时候最好要把保留的像素改变成近似的颜色。

比如我们这里保留了调色板1,2,3,在原先灰度图里,1,2,3其实和颜色0的纯黑色是非常接近的。

int step4(void)

{

int w, h, i;

unsigned char *pImg;

printf("step4: reserve color!\n");

pImg= read_bmp("test.bmp", &w, &h);

if(pImg==NULL) return -1;

//把原始像素值为1,2,3的全部设置为0

for(i=0; i

{

if(pImg[i]==1 || pImg[i]==2 || pImg[i]==3) pImg[i]=0;

}

paint_min(pImg, 98, 79, w, h);

paint_min(pImg, 49, 87, w, h);

draw_rect(pImg,10 ,10 ,110,110, w, h, 2);

draw_rect(pImg,174,156,194,176, w, h, 3);

write_color_bmp("test_color.bmp", pImg, w, h);

return 1;

}

这是输出的测试结果,可以看到我们画出了2个红色的小圈,一个绿色的大矩形框,一个蓝色的小矩形框

5.图像的缩放,线性插值算法

图像的线性插值算法,其实非常简单。

我们先从一维的插值开始推导相关的公式。

如果插值前的长度是w,插值后的长度是w'

那么对于插值后坐标为i的点,在插值前就是x=i*w/w',这个数值如果取整为n=[x],这个位置会落在

n,n+1之间。那么插值后这个点的数值应该是就是点n,n+1的线性插值。

假定插值前的一位数组值是s[w], 插值后的是s2[w']所以一维插值算法如下:

int i,n;

float f;

for(i=0; i

{

f=i*w/w'; n=f; f=f-n;

s2[i]=s[n]*(1-f)+s[n+1]*f;

}

上面是使用浮点数计算法,实际使用的时候可以使用定点方法来计算,我们这里把浮点数扩大1024倍来计算

int i,n,f;

for(i=0; i

{

n=i*w/w'; f=1024*i*w1/w2-1024*n;

s2[i]=(s[n]*(1024-f)+s[n+1]*f)>>10;

}

同样的办法,插值两次就变成了二位图像插值算法。注意,我们临时的图像数组大小是

512*512,插值后的图像

大小不能超过这个,否则会产生内存越界的错误。

void scale_img(unsigned char* pImgIn, int w1, int h1, unsigned char* pImgOut, int w2, int h2)

{

int i, j;

int i0, j0;

int f1, f2;

unsigned char pImg[512*512];

for(j=w2-1; j>=0; j--)

{

j0 = j*w1/w2;

f1 = 1024*j*w1/w2-1024*j0;

f2 = 1024-f1;

for(i=0; i

{

pImg[i*w2+j]=(unsigned

char)((pImgIn[i*w1+j0]*f2+pImgIn[i*w1+j0+1]*f1)>>10);

}

}//宽度插值

for(i=h2-1; i>=0; i--)

{

i0 = i*h1/h2;

f1 = 1024*i*h1/h2-1024*i0;

f2 = 1024-f1;

for(j=0; j

{

pImgOut[i*w2+j]=(unsigned

char)((pImg[i0*w2+j]*f2+pImg[(i0+1)*w2+j]*f1)>>10);

}

}//高度插值

}

下面是把我们的图像插值成原来的88%,125%

int step5(void)

{

int w, h, w2, h2, w3, h3;

unsigned char *pImg, *pImg2, *pImg3;

printf("step5: scale image test!\n");

pImg= read_bmp("test.bmp", &w, &h);

if(pImg==NULL) return -1;

w2=(int)(0.88*w); h2=(int)(0.88*h);

w3=(int)(1.25*w); h3=(int)(1.25*h);

pImg2=(unsigned char*)malloc(256*256);

pImg3=(unsigned char*)malloc(w3*h3);

scale_img(pImg, w, h, pImg2, w2, h2);

write_bmp("test5a.bmp", pImg2, w2, h2);

scale_img(pImg, w, h, pImg3, w3, h3);

write_bmp("test5b.bmp", pImg3, w3, h3);

free(pImg3);

free(pImg2);

return 1;

}

这是插值后的效果图,源代码已经同步更新

bmp文件格式详解

b m p文件格式详解 Company Document number:WTUT-WT88Y-W8BBGB-BWYTT-19998

BMP文件格式,又称为Bitmap(位图)或是DIB(Device-IndependentDevice,设备无关位图),是Windows系统中广泛使用的图像文件格式。由于它可以不作任何变换地保存图像像素域的数据,因此成为我们取得RAW数据的重要来源。Windows的图形用户界面(graphicaluserinterfaces)也在它的内建图像子系统GDI中对BMP格式提供了支持。 下面以Notepad++为分析工具,结合Windows的位图数据结构对BMP文件格式进行一个深度的剖析。 BMP文件的数据按照从文件头开始的先后顺序分为四个部分: bmp文件头(bmpfileheader):提供文件的格式、大小等信息 位图信息头(bitmapinformation):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息 调色板(colorpalette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表 位图数据(bitmapdata):就是图像数据啦^_^ 下面结合Windows结构体的定义,通过一个表来分析这四个部分。 我们一般见到的图像以24位图像为主,即R、G、B三种颜色各用8 个bit来表示,这样的图像我们称为真彩色,这种情况下是不需要调色 板的,也就是所位图信息头后面紧跟的就是位图数据了。因此,我们 常常见到有这样一种说法:位图文件从文件头开始偏移54个字节就是

位图数据了,这其实说的是24或32位图的情况。这也就解释了我们 按照这种程序写出来的程序为什么对某些位图文件没用了。 下面针对一幅特定的图像进行分析,来看看在位图文件中这四个数据 段的排布以及组成。 我们使用的图像显示如下: 这是一幅16位的位图文件,因此它是含有调色板的。 在拉出图像数据进行分析之前,我们首先进行几个约定: 1.在BMP文件中,如果一个数据需要用几个字节来表示的话,那么该数据的存放字节顺序为“低地址村存放低位数据,高地址存放高位数据”。如数据 0x1756在内存中的存储顺序为: 这种存储方式称为小端方式(littleendian),与之相反的是大端方式(bigendian)。对两者的使用情况有兴趣的可以深究一下,其中还是有学问的。 2.以下所有分析均以字节为序号单位进行。 下面我们对从文件中拉出来的数据进行剖析: 一、bmp文件头 Windows为bmp文件头定义了如下结构体: typedef struct tagBITMAPFILEHEADER {?

BMP格式结构详解

位图文件(B it m a p-File,BMP)格式是Windows采用的图像文件存储格式,在Windows环境下运行的所有图像处理软件都支持这种格式。Windows 3.0以前的BMP位图文件格式与显示设备有关,因此把它称为设备相关位图(d evice-d ependent b itmap,DDB)文件格式。Windows 3.0以后的BMP位图文件格式与显示设备无关,因此把这种BMP位图文件格式称为设备无关位图(d evice-i ndependent b itmap,DIB)格式,目的是为了让Windows能够在任何类型的显示设备上显示BMP位图文件。BMP位图文件默认的文件扩展名是BMP或者bmp。 6.1.2 文件结构 位图文件可看成由4个部分组成:位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)和定义位图的字节阵列,它们的名称和符号如表6-01所示。 表6-01 BMP图像文件组成部分的名称和符号 位图文件的组成结构名称符号 位图文件头(bitmap-file header)BITMAPFILEHEADE R bmfh 位图信息头(bitmap-information header)BITMAPINFOHEADE R bmih 彩色表(color table)RGBQUAD aColors[] 图像数据阵列字节BYTE aBitmapBits[ ] 位图文件结构可综合在表6-02中。 表6-02 位图文件结构内容摘要 偏移量域的名称大小内容 图像文件头0000h标识符 (Identifie r) 2 bytes两字节的内容用来识别位图的类型: ‘BM’ : Windows 3.1x, 95, NT, linux ‘BA’ :OS/2 Bitmap Array ‘CI’ :OS/2 Color Icon ‘CP’ :OS/2 Color Pointer ‘IC’ : OS/2 Icon ‘PT’ :OS/2 Pointer 0002h File Size 1 dword用字节表示的整个文件的大小 0006h Reserved 1 dword保留,设置为0 000Ah Bitmap Data Offset 1 dword从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量 000Eh Bitmap Header Size 1 dword位图信息头(Bitmap Info Header)的长度,用来 描述位图的颜色、压缩方法等。下面的长度表示: 28h - Windows 3.1x, 95, NT, … 0Ch - OS/2 1.x F0h - OS/2 2.x 0012h Width 1 dword位图的宽度,以像素为单位 0016h Height 1 dword位图的高度,以像素为单位 001Ah Planes 1 word位图的位面数 图像001Ch Bits Per Pixel 1 word每个像素的位数 1 - Monochrome bitmap

C语言程序中关于文件的操作

文件操作函数C语言(FILE fputc fgetc fputs fgets fscanf fprintf) 在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之。 一、流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下:typedef struct{ int level;/*fill/empty level of buffer*/ unsigned flags;/*File status flags*/ char fd;/*File descriptor*/ unsigned char hold;/*Ungetc char if no buffer*/ int bsize;/*Buffer size*/ unsigned char_FAR*buffer;/*Data transfer buffer*/ unsigned char_FAR*curp;/*Current active pointer*/ unsigned istemp;/*Temporary file indicator*/ short token;/*Used for validity checking*/ }FILE;/*This is the FILE object*/ FILE这个结构包含了文件操作的基本属性,对文件的操作都要通过这个结构的指针来进行,此种文件操作常用的函数见下表函数功能 fopen()打开流 fclose()关闭流 fputc()写一个字符到流中 fgetc()从流中读一个字符 fseek()在流中定位到指定的字符 fputs()写字符串到流 fgets()从流中读一行或指定个字符 fprintf()按格式输出到流 fscanf()从流中按格式读取 feof()到达文件尾时返回真值 ferror()发生错误时返回其值 rewind()复位文件定位器到文件开始处 remove()删除文件 fread()从流中读指定个数的字符 fwrite()向流中写指定个数的字符 tmpfile()生成一个临时文件流 tmpnam()生成一个唯一的文件名 下面就介绍一下这些函数 1.fopen() fopen的原型是:FILE*fopen(const char*filename,const char*mode),fopen实现三个功

Linux下C语言的文件读写

Linux下C语言的文件(fputc,fgetc,fwrite,fread对文件读写操 作) //================================== fputc 向文件写入字符 #include #include main() { FILE *fp; char ch; if((fp=fopen("test.txt","w"))==NULL) { printf("不能打开文件\n"); exit(0); } while ((ch=getchar())!='\n') fputc( ch, fp ); fclose(fp); } ------------- 小提示: fp=fopen("test.txt","w") ,把"w"改为"a" 可以创建文件并且追加写入内容 exit(0); 需要包含stdlib.h 头文件,才能使用 //============================================================ fgetc 读取字符 #include #include main( int argc, char *argv[] ) { char ch;

FILE *fp; int i; if((fp=fopen(argv[1],"r"))==NULL) { printf("不能打开文件\n"); exit(0); } while ((ch=fgetc(fp))!=EOF) putchar(ch); fclose(fp); } 文件结尾,通过判断EOF //============================================================== fwrite 的使用 使数组或结构体等类型可以进行一次性读写 #include #include main() { FILE *fp1; int i; struct student{ char name[10]; int age; float score[2]; char addr[15]; }stu; if((fp1=fopen("test.txt","wb"))==NULL) { printf("不能打开文件"); exit(0); } printf("请输入信息,姓名年龄分数1 分数2 地址:\n"); for( i=0;i<2;i++) { scanf("%s %d %f %f %s",https://www.sodocs.net/doc/281182809.html,,&stu.age,&stu.score[0],&stu.score[1], stu.addr);

位图结构详细资料

GDI基本概念及思想 编写代码的一般步骤:先用CreateDC创建(或GetDC获取)device content(DC),然后用GetObject获取(或使用创建object的函数创建)需要的object,并用SelectObject将获取的object选入device content(DC),再使用object进行相应的画图操作,最后用SelectObject将原来的object重新选入DC,并delete 或release删除或释放前面创建或获取的DC。 1.关于device context (DC)设备内容:用来显示位图的地方. 四种设备内容:显示器设备内容、打印机设备内容、内存设备内容、Information 设备内容,常用的有显示器DC和内存DC. Device Context Types: There are four types of DCs: display, printer, memory (or compatible), and information. Device context Description Display Supports drawing operations on a video display. Printer Supports drawing operations on a printer or plotter. Memory Supports drawing operations on a bitmap. Information Supports the retrieval of device data. 其中需要注意的一种类型是:Memory Device Contexts,将在bitmap处理中详细介绍。 创建和获取DC的相关函数: CreateDC,CreateCompatibleDC,GetDC,GetCurrentDC. 其中CreateCompatibleDC用于创建内存设备内容. 刷新、释放和删除DC的相关函数: ResetDC,ReleaseDC,DeleteDC.前者当DC有变动时用来重置DC,后者用来释放使用万完的DC. DeleteDC与CreateDC对应使用 ReleaseDC与GetDC对应使用 2.关于graphical object(GDI objects): 包括:pen,brush,bitmap,palette,region,path. 获取、选择和删除object的相关函数:

c语言文件的读写格式

C程序文件的读写操作 在对文件进行读、写操作之前,首先要解决的问题是如何把程序中要读、写的文件与磁盘上实际的数据文件联系起来。在c语言中,其实这并不困难,只需要用c语言提供的库函数fopen“打开”文件就可以实现这些联系。Fopen函数的一般调用形式为: Fopen(文件名,文件使用方式); 函数返回一个指向file类型的指针。例如: FILE *fp; /*****定义一个文件指针*/ fp=fopen(”file_a”,”r”); foen函数调用中用两个字符串作为参数。第一个字符串中包含了进行读、写操作的文件名,用来指定所要打开的文件。在本例中,指定的函数名:file_a。第二个字符串中指定了文件的使用方式,用户可通过这个参数来指定对文件的使用意图。 如果以上函数调用成功,函数返回一个fille类型的指针,付给指针变量fp,从而把指针fp与文件file_a联系起来,也就是说,在此调用之后,指针fp就指向了文件file_a。 C语言中,最常用的文件使用用方式及其含义如下: (1)“r”。为读而打开文本文件。当指定这种形式时,对打开的文件只能进行“读”操作。若制定的文件不存在,则会出错,若去读一个不允许读的文件时也会出错。 (2)“rb”。为读而打开一个二进制文件,其余如“r”功能。 (3)“w”。为写而打开文本文件。这是。如果指定的文件不存在,系统将在指定位置建立一个新文件;如果文件已经存在,则将从文件的起始位置开始写,文件中原有内容将全部覆盖。 (4)“WB”. 为读而打开一个二进制文件,其余如“w”功能。 (5)“a”。为在文件后面添加数据而打开文本文件。这是。如果指定的文件不存在,系统将在指定位置建立一个新文件;如果文件已经存在,则将从文件的末尾位置开始写,文件中原有内容将保留。 (6)“ab”。为读而打开一个二进制文件,其余如“a”功能。 (7)“r+”。为读和写而打开文本文件。用这种方式时,指定的文件应当已经存在,既可以对文件进行读,也可以进行写。读写都是从文件起始位置开始。 关闭文件: fclose(文件指针); 程序例子: #include #include //fputc和fgetc函数所在文件 main() { FILE *fp=NULL; //定义文件指针 char ch; //定义字符变量 fp=fopen("d:\\wenjian.txt","w"); //打开或新建打开文件,并使指针 //指向文件 if(fp==NULL)

C语言 BMP图片处理

C语言BMP图片处理 BMP是bitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。在系统中以BMP为扩展名保存。 打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。这是最普通的生成位图的工具,在这里讲解的BMP位图形式,主要就是指用画图生成的位图(当然,也可以用其它工具软件生成)。 现在讲解BMP的4个组成部分: 1.文件头信息块 0000-0001:文件标识,为字母ASCII码“BM”。 0002-0005:文件大小。 0006-0009:保留,每字节以“00”填写。 000A-000D:记录图像数据区的起始位置。各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)。 2.图像描述信息块 000E-0011:图像描述信息块的大小,常为28H。 0012-0015:图像宽度。 0016-0019:图像高度。 001A-001B:图像的plane(平面?)总数(恒为1)。 001C-001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩)。0022-0025:图像区数据的大小。 0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。 002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。 002E-0031:此图像所用的颜色数,如值为0,表示所有颜色一样重要。 3.颜色表 颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(像素的透明度值,一般不需要)。即首先4字节表示颜色号0的颜色,接下来表示颜色号1的颜色,依此类推。 4.图像数据区

位图文件结构

位图文件结构 1.位图文件头(BITMAPFILEHEADER):14字节 typedef struct tagBITMAPGILEHEADER{ WORD bfType; //值为0x4d42 DWORD bfSize; //位图文件的大小 WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMATPFILEHEADER; 2.位图信息: typedef struct tagBITMAPINFO{ BITMAPINFOHEADER bmiHeader; //位图信息头 RGBQUAD bmiColors; //颜色表 } BITMAPINFO; 1)位图信息头: typedef struct tagBITMAPINFOHEADER{ DWORD biSize; //位图信息头的字节数sizeof(BITMAPINFOHEADER) LONG biWidth; //以像素为单位的图像宽度 LONG biHeight; //以像素为单位的图像长度 WORD biPlanes; //目标设备的位平面数 WORD biBitCount; //每个像素的位数【1】 DWORD biCompression; //图像的压缩格式(这个值几乎总是为0) DWORD biSizeImage; //以字节为单位的图像数据的大小 LONG biXpelsPerMeter; //水平方向上的每米的像素个数 LONG biYpelsPerMeter; //垂直方向上的每米的像素个数 DWORD biClrUsed; //调色板中实际使用的颜色数,通常为0 DWORD biClrImportant; //实现位图时必须的颜色数,通常为0 } BITMAPINFOHEADER; 【1】每个像素的位数 0,用在JPEG格式中 1,单色图,调色板中含有两种颜色,也就是我们通常说的黑白图片 4,16色图 8,256色图,通常说的灰度图 16,64K图,一般没有调色板,图像数据中每两个字节表示一个图像,5个或6个位表示一个RGB分量 24,16M真彩色图,一般没有调色板,图像数据中每3个字节表示一个像素,每个字节表示一个RGB分量 32,4G真彩色,一般没有调色板,每4个字节表示一个像素,相对24位真彩图而言,加入了一个透明度,即RGBA模式 2)颜色表: 针对16位以下的图像而设置的。对于16位以下的图像,由于其位图像素数据中记 录的只是调色板索引值,因而需要根据这个索引到调色板去取得相应的RGB颜色。 typedef struct tagRGBQUAD{ BYTE rgbBlue;

C语言读写文件操作

C语言读写文件操作 #include #include #include FILE *stream;//, *stream2; FILE *stream2; void main( void ) { int numclosed; char *list; list="这个程序由czw编写"; //试图打开文件data.txt,如果该文件不存在,则自动创建 if( (stream= fopen( "data.txt", "r" )) == NULL ) { printf( "试图打开'data.txt'\n" ); printf( "'data.txt'不存在\n" ); printf( "'data.txt'被创建\n" ); } else printf( "'data.txt'被打开\n" ); //以写入方式打开 if( (stream2 = fopen( "data.txt", "w+" )) == NULL ) printf( "'data.txt'不存在\n" ); else { printf( "'data.txt'成功被打开\n" ); fwrite(list,strlen(list),30,stream2); printf("写入数据成功\n"); } //如果文件data.txt存在,就会打开成功,则stream!=NULL,这时就关闭stream if (stream!=NULL) if( fclose( stream) ) printf( "文件流 stream 被关闭\n" ); //关闭所有打开的文件流,返回关闭的文件流个数 numclosed = _fcloseall( );

C语言中文件_数据的输入输出_读写

C语言中文件,数据的输入输出,读写. 文件是数据的集合体,对文件的处理过程就是对文件的读写过程,或输入输出过程。 所谓文件是指内存以外的媒体上以某种形式组织的一组相关数据的有序集合。文件分类: 顺序文件,随机文件。 文本文件和二进制文件。 文本文件也称为ASCII文件,在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。 文本文件可以在屏幕上按字符显示,源程序文件就是文本文件,由于是按字符显示,所以能读懂文件内容。 二进制文件是按二进制编码方式来存放的。这里主要讨论文件的打开,关闭,读,写,定位等操作。 文件的存取方法 C程序的输入输出(I/O)有两种方式:一种称为标准I/O或流式I/O,另一种称为低级I/O。流式I/O是依靠标准库函数中的输入输出函数实现的。低级I/O利用操作系统提供的接口函数(称为底层接口或系统调用)实现输入输出,低级I/O 主要提供系统软件使用。 在C语言中用一个FILE类型的指针变量指向一个文件,(FILE类型是系统在stdio.h中定义的描述已打开文件的一种结构类型),这个指针称为文件指针。FILE *指针变量标识符; 如 FILE *fp; 文件的打开与关闭 所谓打开文件,指的是建立文件的各种有关信息,并使文件指针指向该文件,以便对它进行操作。 关闭文件则是断开指针与文件之间的联系,也就禁止再对该文件进行操作。 1、fopen 函数原型:FILE *fopen(const char *filename,const char *mode); Fopen函数用来打开一个文件,前一部分用来说明文件路径及文件名,后一部分mode指出了打开文件的存取方式;返回值是被打开文件的FILE型指针,若打开失败,则返回NULL。打开文件的语法格式如下: 文件指针名=fopen(文件名,使用文件方式); 文件指针名必须被说明为FILE类型的指针变量。 FILE *fp; fp=fopen(“C:\\Windowss\\abc.txt”,”r”); 注意用两个反斜杠\\来表示目录间的间隔符。 存取文件的模式是一个字符串,可以由字母r,w,a,t,b及+组合而成,各字符的含

BMP文件格式

BMP文件格式 简介 BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Wi ndows系统内部各图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependent bitmap)文件格式。Windows 3.0以后的BMP图象文件与显示设备无关,因此把这种BM P图象文件格式称为设备无关位图DIB(device-independent bitmap)格式(注:Windows 3.0以后,在系统中仍然存在DDB位图,象BitBl t()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB 或.RLE作扩展名)。 此图用WinHex软件打开后结果如下:(在介绍完bmp文件格式后会具体分析这些数字,最后也有matlab对此图的分析)注:此图是24位真彩色图。 文件结构 位图文件可看成由4个部分组成:位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)和定义位图的字节阵列,它具有如下所示的形式。

位图文件结构可综合在表6-01中。表01 位图文件结构内容摘要

构件详解 1. 位图文件头 位图文件头包含有关于文件类型、文件大小、存放位置等信息,在Windows 3.0以上版本的位图文件中用BITMAPFILEHEADER结构来定义: typedef struct tagBITMAPFILEHEADER { /* bmfh */ UINT bfType; DWORD bfSize; UINT bfReserved1; UINT bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER; 其中: bfType 说明文件的类型.(该值必需是0x4D42,也就是字符'BM'。我们不需要判断OS/2的位图标识,这么做现在来看似乎已经没有什么意义了,而且如果要支持OS/2的位图,程序将变得很繁琐。所以,在此只建议你检察'BM'标识) bfSize 说明文件的大小,用字节为单位bfReserved1 保留,必须设置为0

BMP头文件格式

bmp头文件格式 1:BMP文件组成 BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。2:BMP文件头(14字节) BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。 其结构定义如下: typedef struct tagBITMAPFILEHEADER { WORDbf Type; // 位图文件的类型,必须为BMP(0-1字节) DWORD bfSize; // 位图文件的大小,以字节为单位(2-5字节) WORD bfReserved1; // 位图文件保留字,必须为0(6-7字节) WORD bfReserved2; // 位图文件保留字,必须为0(8-9字节) DWORD bfOffBits; // 位图数据的起始位置,以相对于位图(10-13字节) // 文件头的偏移量表示,以字节为单位 } BITMAPFILEHEADER; 3:位图信息头(40字节) BMP位图信息头数据用于说明位图的尺寸等信息。 typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // 本结构所占用字节数(14-17字节) LONG biWidth; // 位图的宽度,以像素为单位(18-21字节)

LONG biHeight; // 位图的高度,以像素为单位(22-25字节) WORD biPlanes; // 目标设备的级别,必须为1(26-27字节) WORD biBitCount;// 每个像素所需的位数,必须是1(双色),(28-29字节) // 4(16色),8(256色)或24(真彩色)之一 DWORD biCompression; // 位图压缩类型,必须是0(不压缩),(30-33字节) // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 DWORD biSizeImage; // 位图的大小,以字节为单位(34-37字节) LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数(38-41字节) LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数(42-45字节) DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数(46-49字节) DWORD biClrImportant;// 位图显示过程中重要的颜色数(50-53字节) } BITMAPINFOHEADER; 4:颜色表 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: typedef struct tagRGBQUAD {

C语言文件读写函数集合

C语言文件读写函数 1.fopen() fopen的原型是:FILE *fopen(const char *filename,const char *mode),fopen 实现三个功能:为使用而打开一个流,把一个文件和此流相连接,给此流返回一个FILR指针。 参数filename指向要打开的文件名,mode表示打开状态的字符串,其取值如下: 字符串含义 "r" 以只读方式打开文件 "w" 以只写方式打开文件 "a" 以追加方式打开文件 "r+" 以读/写方式打开文件,如无文件出错 "w+" 以读/写方式打开文件,如无文件生成新文件 一个文件可以以文本模式或二进制模式打开,这两种的区别是:在文本模式中回车被当成一个字符’/n’,而二进制模式认为它是两个字符0x0D,0x0A;如果在文件中读到0x1B,文本模式会认为这是文件结束符,也就是二进制模型不会对文件进行处理,而文本方式会按一定的方式对数据作相应的转换。

系统默认的是以文本模式打开,可以修改全部变量_fmode的值来修改这个设置,例如_fmode=O_TEXT;就设置默认打开方式为文本模式;而 _fmode=O_BINARY;则设置默认打开方式是二进制模式。 我们也可以在模式字符串中指定打开的模式,如"rb"表示以二进制模式打开只读文件,"w+t"或"wt+"表示以文本模式打开读/写文件。 此函数返回一个FILE指针,所以申明一个FILE指针后不用初始化,而是用fopen()来返回一个指针并与一个特定的文件相连,如果成败,返回NULL. 例: 以下是引用片段: FILE *fp; if(fp=fopen("123.456","wb")) puts("打开文件成功"); else puts("打开文件成败"); 2.fclose() fclose()的功能就是关闭用fopen()打开的文件,其原型是:int fclose(FILE *fp);如果成功,返回0,失败返回EOF。 在程序结束时一定要记得关闭打开的文件,不然可能会造成数据丢失的情况,我以前就经常犯这样的错误。 例:fclose(fp); 3.fputc()

bmpTesth介绍BMP文件的格式及结构定义

bmpTest.h : 介绍BMP 文件的格式及结构定义 bmpTest.cpp : 24bitBMP 颜色数据到256 色位图颜色数据的转换函数实现,具体算法可参考以前的一个帖子bmpTransfer.cpp : 读入一个24bitBMP 文件,转换成一个256 色BMP 文件的程序 编译完成后得到的程序,如bmpTransfer.exe 执行bmpTransfer file1 file2 file1 是24bit 的BMP 位图源文件名,file2 是新生成的256 色位图文件名 可以用windows 画板程序查看结果,似乎比直接用画板程序将24bitBMP 存成256 色BMP 文件的转换效果要好哦。 /************* bmpTest.h **************/ #ifndef __BMPTEST_H_ #define __BMPTEST_H #include typedef unsigned char BYTE; typedef unsigned short WORD; // BMP 图像各部分说明如下 /*********** 第一部分位图文件头 该结构的长度是固定的,为14 个字节,各个域的依次如下: 2byte :文件类型,必须是0x4d42 ,即字符串"BM" 。 4byte :整个文件大小 4byte :保留字,为0 4byte :从文件头到实际的位图图像数据的偏移字节数。*************/ typedef struct { long imageSize; long blank; long startPosition; void show(void) { printf("BMP Head:\n"); printf("Image Size:%d\n",imageSize); printf("Image Data Start Position : %d\n",startPosition); } }BmpHead; /********************* 第二部分位图信息头该结构的长度也是固定的,为40 个字节,各个域的依次说明如下: 4byte :本结构的长度,值为40

C语言文件操作命令

C语言文件操作函数大全 clearerr(清除文件流的错误旗标) 相关函数 feof 表头文件 #include 定义函数 void clearerr(FILE * stream); 函数说明 clearerr()清除参数stream指定的文件流所使用的错误旗标。 返回值 fclose(关闭文件) 相关函数 close,fflush,fopen,setbuf 表头文件 #include 定义函数 int fclose(FILE * stream); 函数说明 fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。 返回值若关文件动作成功则返回0,有错误发生时则返回EOF并把错误代码存到errno。 错误代码 EBADF表示参数stream非已打开的文件。 范例请参考fopen()。 fdopen(将文件描述词转为文件指针) 相关函数 fopen,open,fclose 表头文件 #include 定义函数 FILE * fdopen(int fildes,const char * mode); 函数说明 fdopen()会将参数fildes 的文件描述词,转换为对应的文件指针后返回。参数mode 字符串则代表着文件指针的流形态,此形态必须和原先文件描述词读写模式相同。关于mode 字符串格式请参考fopen()。 返回值转换成功时返回指向该流的文件指针。失败则返回NULL,并把错误代码存在errno中。 范例 #include main() { FILE * fp =fdopen(0,”w+”); fprintf(fp,”%s\n”,”hello!”); fclose(fp); } 执行 hello! feof(检查文件流是否读到了文件尾) 相关函数 fopen,fgetc,fgets,fread 表头文件 #include 定义函数 int feof(FILE * stream); 函数说明 feof()用来侦测是否读取到了文件尾,尾数stream为fopen()所返

BMP图像格式分析

BMP图像格式分析 BMP图像文件格式是微软公司为其Windows环境设置的标准图像格式,而且 Windows系统软件中还同时内含了一系列支持BMP图像处理的API函数,随着Windows 在世界范围内的不断普及,BMP文件格式无疑也已经成为PC机上的流行图像文件格式。它的主要特点可以概括为:文件结构与PCX文件格式类似,每个文件只能存放一幅图像;图像数据是否采用压缩方式存放,取决于文件的大小与格式,即压缩处理成为图像文件的一个选项,用户可以根据需要进行选择。其中,非压缩格式是BMP图像文件所采用的一种通用格式。但是,如果用户确定将BMP文件格式压缩处理,则Windows设计了两种压缩方式:如果图像为16色模式,则采用RLE4压缩方式,若图像为256色模式,则采用RLE8压缩方式。同时,BMP 图像文件格式可以存储单色、16色、256色以及真彩色四种图像数据,,其数据的排列顺序与一般文件不同,它以图像的左下角为起点存储图像,而不是以图像的左上角为起点;而且BMP图像文件格式中还存在另外一个与众不同的特点,即其调色板数据所采用的数据结构中,红、绿、蓝三种基色数据的排列顺序也恰好与其它图像文件格式相反。总之,BMP图像文件格式拥有许多适合于Windows环境的新特色,而且随着Windows版本的不断更新,微软公司也在不断改进其BMP 图像文件格式,例如:当前BMP图像文件版本中允许采用32位颜色表,而且针对32位Windows 的产生,相应的API 函数也在不断地报陈出新,这些无疑都同时促成了BMP文件格式的不断风靡。但由于BMP文件格式只适合于Windows上的应用软件,而对于DOS环境中的各种应用软件则无法提供相应的支持手段,因此这无疑是阻碍BMP文件格式的流通程度超过PCX文件格式的一个重要因素。 Windows中定义了两种位图文件类型,即一般位图文件格式与设备无关位图文件格式。其中,由于设备无关位图(DIB)文件格式具有更强的灵活性与完整的图像数据、压缩方式等定义。BMP图像文件的结构可以分为如下三个部分:文件头、调色板数据以及图像数据。其中文件头的长度为固定值54个字节;调色板数据对所有不超过256色的图像模式都需要进行设置,即使是单色图像模式也不例外,但是对于真彩色图像模式,其对应的BMP文件结构中却不存在相应调色板数据的设置信息;图像数据既可以采用一定的压缩算法进行处理,也可以不必对图像数据进行压缩处理,这不仅与图像文件的大小相关,而且也与对应的图像处理软件是否支持经过压缩处理的BMP图像文件相关。以下将分别介绍BMP图像文件结构中的这三个重要组成部分。特别值得注意的是:BMP 图像文件结构设计得相当简单,这无疑有利于图像文件的处理速度,但是同时也使得 BMP图像文件格式具有一定的局限性,即一个BMP图像文件只能存储一幅图像。 BMP图像文件的文件头定义 Windows中将BMP图像文件的文件头分成两个数据结构,其中一个数据结构中包含BMP文件的类型、大小和打印格式等信息,称为BITMAPFILEHEADERl另外一个数据结构中则包含BMP文件的尺寸定义等信息,称为BITMAPINFOHEADERl 如果图像文件还需要调色板数据,则将其存放在文件头信息之后。 BITMAPFIlEHEADER数据结构在Windows.h中的定义为: typedef struCttagBITMAPFIlEHEADER { WORD bftype; DWORD bfsiZe: WORD bfReservedl; WORD bgReserved2: DWORD bfoffBits: }BITMAPFILEHEADER; 其中,bfrype在图像文件存储空间中的数据地址为0,数据类型为unsignedchar,内容为固定值“BM”,用于标志文件格式,表示该图像文件为BMP文件。 bfsize的数据地址为2,类型为unsignedlong,它以字节为单位,定义位图文件的大小。 bfReservedl与bfReserved2的数据地址分别为6和8,数据类型则都为unsignedint,二者都是BMP文件的保留字,没有任何意义,其值必须为0. bfoffBits的数据地址为10,数据类型为unsignedlong,它以字节为单位,指示图像数据在文件内的起始地址,即图像数

bmp文件结构的探索 (1)

BMP文件结构的探索 BMP文件结构的探索 WhatIf 2004-9-10 一、文件格式 Bmp文件是非常常用的位图文件,无论是游戏还是其他都被广泛使用。针对bmp文件的处理也有一堆现成的api进行调用,然而文件内部究竟怎样,如何自己来解析这样的文件呢?为了消除无聊,我用了几天时间来研究了一下,同时作为学习笔记,进行记录。 首先,整个bmp文件的内容可以分为3到4块。之所以分为3到4块而不是固定的值,是因为,对于bmp来说可能存在调色板或者一些掩码。具体稍候讨论。 第一块是bmp的文件头用于描述整个bmp文件的情况。结构如下:typedef struct BITMAPFILEHEADER { WORD bfType; //两个字节 DWORD bfSize; //四个字节 WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, *PBITMAPFILEHEADER; 这些信息相当有用,如果你想直接来解析bmp文件。第一个bfType用于表示文件类型,如果它是bmp文件,那么它这个位置的值一定是”BM”也就是0x4D42。第二个bfSize表示整个文件的字节

数。第三第四个则保留,目前无意义,最后一个相当重要,表示,位图的数据信息离文件头的偏移量,以字节为单位。 第二块是位图信息头,即BITMAPINFOHEADER,用于描述整个位图文件的情况。以下挑重要的数据进行解释 typedef struct BITMAPINFOHEADER{ DWORD biSize; //表示本结构的大小 LONG biWidth; //位图的宽度 LONG biHeight; //位图的高度 WORD biPlanes; //永远为1 ,由于没有用过所以没做研究附msdn解释 //Specifies the number of planes for the target device. This value must be set to 1. WORD biBitCount;//位图的位数分为1 4 8 16 24 32 本文没对1 4 进行研究 DWORD biCompression; //本以为压缩类型,但是却另外有作用,稍候解释 DWORD biSizeImage; //表示位图数据区域的大小以字节为单位 LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant;

相关主题