用标准c读取某bmp文件的长宽及象素等信息需要哪些函数?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用标准c读取某bmp文件的长宽及象素等信息需要哪些函数?相关的知识,希望对你有一定的参考价值。
最好有段代码
最好能有注释。
bmp文件存贮形式为前14个字节为文件信息区,保存的是BMP文件类型标识2,文件长度4,保留字节4,文件描述区长度4,(其中16色位图值为118,256色位图为1078)。
之后40个字节是图像信息区,为图形尺寸4,图形宽度4,图形高度4,其他就不多说了,你可看下关于BMP文件的说明。
因此读取长宽只要从文件头偏移18字节就行。
#include <stdio.h>
main()
long bmpwidth,bmpheight;
FILE *fp;
fp=fopen("FIVEANGL.bmp","rb");
fseek(fp,18L,SEEK_SET);
fread(&bmpwidth,4,1,fp);
fread(&bmpheight,4,1,fp);
fclose(fp);
printf("\n%s width is %ld,height is %ld","FIVEANGL.bmp",bmpwidth,bmpheight);
getchar();
参考技术A #include <stdio.h>
#include <stdlib.h>
//#define BUFFSIZE 1024
#define WIDTH 10
unsigned char head[1078];
unsigned char pix[WIDTH][WIDTH];
int width=WIDTH;
int heigh;
void pixread(FILE *fpin);
void headread(FILE *fpin);
void newbmp();
int main()
//int datanum;
//int i;
FILE *bmpfp=NULL;
//int width=WIDTH;
///mnt/win1/mywork/picture-process/32
if((bmpfp=fopen("10x10.bmp","rb"))==NULL)
printf("Read the bmp file has failed\n");
exit(1);
headread(bmpfp);
pixread(bmpfp);
newbmp();
fclose(bmpfp);
return 0;
void headread(FILE *fpin) //read the bmp file head 1078 byte
int num1;
num1=fread(head,sizeof(char),1078,fpin);
printf("You have successfully read %d data from bmp file\n",num1);
void pixread(FILE *fpin) //read the bmp file pixels data 32*32 byte
int num2 ;
int i,j;
int count;
unsigned char *pixbuff=NULL;
heigh=10;
width=32;
fseek(fpin,1078,0);
if((pixbuff=(unsigned char *)malloc(sizeof(char)*320))==NULL)
printf("Data memory allocation fail!\n");
num2=fread(pixbuff,sizeof(char),1024,fpin);
printf("You have successfully read %d data from the bmp file\n",num2);
for(i=(heigh-1);i>=0;i--)
count=width-1-i;
for(j=0;j<width;j++)
pix[i][j]=pixbuff[count*width+j];
free(pixbuff);
pixbuff=NULL;
heigh=10;
width=32;
printf("The data are\n");
for(i=0;i<heigh;i++)
for(j=0;j<width;j++)
printf("%d ",pix[i][j]);
printf("\n");
//BeginWaitCursor();
printf("Read the data end\n");
void newbmp() //write the data that has some change to new bmp file
int i,j;
int num3;
int num4;
int count;
//unsigned char pixbuff[1024];
FILE *newfp;
unsigned char *pixbuff=NULL;
for(i=1;i<32;i++)
pix[16][i]=pix[15][i]=0; //make a small change about old bmp file
newfp=fopen("c:\new1.bmp","wb");///mnt/win1/mywork/picture-process/pgm/
num3=fwrite(head,sizeof(char),1078,newfp);
printf("You have successfully write %d data to new bmp file\n",num3);
if((pixbuff=(unsigned char *)malloc(sizeof(char)*width*width))==NULL)
printf(" Data memory allocation fail!\n");
width=32; //because the global var has changed
for(i=(width-1);i>=0;i--)
count=width-1-i;
for(j=0;j<width;j++)
pixbuff[count*width+j]=pix[i][j];
//for(i=1;i<1025;i++) //display the data
// printf("%d ",pixbuf[i]);
// if(i%32==0)
// putchar('\n');
//
//
fseek(newfp,1078,0);
num4=fwrite(pixbuff,sizeof(char),1024,newfp);
printf("You have successfully write %d data to new bmp file\n",num4);
free(pixbuff);
pixbuff=NULL;
//根据图象的bitcounts不同,数组定义也不同,如24位BMP图象,3字节表示一像素
参考资料:http://blog.csdn.net/zzzzluo/archive/2006/05/29/761447.aspx
参考技术B fread()fgetc() 参考技术C 什么函数都不需要,只需要了解bmp文件格式就可以了。
用标准c读取bmp文件的长宽?
要求头文件只包括 "stdlib.h"和"stdio.h"
http://zhidao.baidu.com/question/80147331.html同一个问题如果答案准确的话,此分也奉上。最好自己写要求头文件只有stdio.h和stdlib.h。不要贴那么多无关的东西。
读取bmp文件的长宽,要自己写函数的,首先需要对bmp的格式有所了解。
下面是bmp的格式,可以看出“位图信息头”的结构中有宽度和高度的信息
只需要把“位图信息头”读取出来,就能获取到bmp文件的宽度和高度了
而下面的“显示bmp”的源代码中,就有获取”位图信息头的功能。
http://blog.gisforum.net/u/69679/archives/2007/1596.html
1. BMP文件组成
BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
2. 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;
/*显示一个bmp文件的C程序
下面的函数LoadBmpFile,其功能是从一个.bmp文件中读取数据(包括BITMAPINFOHEADER,调色板和实际图象数据)
将其存储在一个全局内存句柄hImgData中,这个hImgData将在以后的图象处理程序中用到。
同时填写一个类型为HBITMAP的全局变量hBitmap和一个类型为HPALETTE的全局变量hPalette。
这两个变量将在处理WM_PAINT消息时用到,用来显示出位图。
该函数的两个参数分别是用来显示位图的窗口句柄,和.bmp文件名(全路径),
当函数成功时,返回TRUE,否则返回FALSE.
*/
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
BOOL LoadBmpFile(HWND hWnd,char* BmpFileName)
HFILE hf; //文件句柄
LPBITMAPINFOHEADER lpImgData; //指向BITMAPINFOHEADER结构的指针
LOGPALETTE *pPal; //指向逻辑调色板结构的指针
LPRGBQUAD lpRGB; //指向RGBQUAD结构的指针
HPALETTE hPrevPalette;//用来保存设备中原来的调色板
HDC hDc; //设备句柄
HLOCAL hPal; //存储调色板的局部内存句柄
DWORD LineBytes; //每一行的字节数
DWORD ImgSize; //实际的图象数据占用的字节数
DWORD NumColors; //实际用到的颜色数,即调色板数组中的颜色个数
DWORD i;
if((hf=_lopen(BmpFileName,OF_READ))==HFILE_ERROR)
MessageBox (hWnd,"Filec:\test.bmpnotfound!","ErrorMessage",
MB_OK|MB_ICONEXCLAMATION);
return FALSE;//打开文件错误,返回
//将BITMAPFILEHEADER结构从文件中读出,填写到bf中
_lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));
//将BITMAPINFOHEADER结构从文件中读出,填写到bi中
_lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
/**//*我们定义了一个宏#define WIDTHBYTES(i) ((i+31)/32*4),上面曾经提到过,每一行的字节数必须是4的整倍数,只要调用WIDTHBYTES(bi.biWidth*bi.biBitCount)就能完成这一换算.举一个例子,对于2色图,如果图象宽是31,则每一行需要31位存储,合3个字节加7位,因为字节数必须是4的整倍数,所以应该是4,而此时的biWidth=31,biBitCount=1,WIDTHBYTES(31*1)=4,和我们设想的一样。再举一个256色的例子,如果图象宽是31,则每一行需要31个字节存储,因为字节数必须是4的整倍数,所以应该是32,而此时的biWidth=31,biBitCount=8,WIDTHBYTES(31*8)=32,和我们设想的一样。你可以多举几个例子来验证一下*/
//LineBytes为每一行的字节数
LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
//ImgSize为实际的图象数据占用的字节数
ImgSize=(DWORD)LineBytes*bi.biHeight;
//NumColors为实际用到的颜色数,即调色板数组中的颜色个数
if(bi.biClrUsed!=0)
NumColors=(DWORD)bi.biClrUsed;//如果bi.biClrUsed不为零,就是本图象实际
//用到的颜色数
else//否则,用到的颜色数为2的biBitCount次方。
switch(bi.biBitCount)
case1:
NumColors=2;
break;
case4:
NumColors=16;
break;
case8:
NumColors=256;
break;
case24:
NumColors=0;//对于真彩色图,没用到调色板
break;
default:
//不处理其它的颜色数,认为出错。
MessageBox(hWnd,"Invalidcolornumbers!","ErrorMessage",
MB_OK|MB_ICONEXCLAMATION);
_lclose(hf);
return FALSE;//关闭文件,返回FALSE
if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)))
//计算出的偏移量与实际偏移量不符,一定是颜色数出错
MessageBox(hWnd,"Invalidcolornumbers!","ErrorMessage",
MB_OK|MB_ICONEXCLAMATION);
_lclose(hf);
return FALSE;//关闭文件,返回FALSE
bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors
*sizeof(RGBQUAD)+ImgSize;
//分配内存,大小为BITMAPINFOHEADER结构长度加调色板+实际位图数据
if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
//分配内存错误
MessageBox(hWnd,"Errorallocmemory!","ErrorMessage",
MB_OK|MB_ICONEXCLAMATION);
_lclose(hf);
return FALSE;//关闭文件,返回FALSE
//指针lpImgData指向该内存区
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
//文件指针重新定位到BITMAPINFOHEADER开始处
_llseek(hf,sizeof(BITMAPFILEHEADER),SEEK_SET);
//将文件内容读入lpImgData
_hread(hf,(char*)lpImgData,(long)sizeof(BITMAPINFOHEADER)
+(long)NumColors*sizeof(RGBQUAD)+ImgSize);
_lclose(hf);//关闭文件
if(NumColors!=0) //NumColors不为零,说明用到了调色板
//为逻辑调色板分配局部内存,大小为逻辑调色板结构长度加NumColors个
//PALETTENTRY大小
hPal=LocalAlloc(LHND,sizeof(LOGPALETTE)+NumColors*sizeof(PALETTEENTRY));
//指针pPal指向该内存区
pPal=(LOGPALETTE*)LocalLock(hPal);
//填写逻辑调色板结构的头
pPal->palNumEntries=NumColors;
pPal->palVersion=0x300;
//lpRGB指向的是调色板开始的位置
lpRGB=(LPRGBQUAD)((LPSTR)lpImgData+(DWORD)sizeof(BITMAPINFOHEADER));
//填写每一项
for(i=0;i<NumColors;i++)
pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
pPal->palPalEntry[i].peFlags=(BYTE)0;
lpRGB++;//指针移到下一项
//产生逻辑调色板,hPalette是一个全局变量
hPalette=CreatePalette(pPal);
//释放局部内存
LocalUnlock(hPal);
LocalFree(hPal);
//获得设备上下文句柄
hDc=GetDC(hWnd);
if(hPalette)//如果刚才产生了逻辑调色板
//将新的逻辑调色板选入DC,将旧的逻辑调色板句柄保存在hPrevPalette
hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
RealizePalette(hDc);
//产生位图句柄
hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData,(LONG)CBM_INIT,
(LPSTR)lpImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),
(LPBITMAPINFO)lpImgData,DIB_RGB_COLORS);
//将原来的调色板(如果有的话)选入设备上下文句柄
if(hPalette&&hPrevPalette)
SelectPalette(hDc,hPrevPalette,FALSE);
RealizePalette(hDc);
ReleaseDC(hWnd,hDc); //释放设备上下文
GlobalUnlock(hImgData); //解锁内存区
Return TRUE; //成功返回
参考技术A #include<stdio.h>
#include<stdlib.h>
typedef struct tagBITMAPINFOHEADER
int bisize;//本结构大小字节为单位
int width;//图形宽度以象素为单位
int height;//图形高度以象素为单位
int planes;//目标设备的级别,必须为1
int bitcount;//每个象素所需要的位数
int SizeImage; // 位图的大小,以字节为单位
int compression;//是否为压缩
int xpermeter;//位图水平分辨率,每米像素数
int ypermeter;// 位图垂直分辨率,每米像素数
int ClrUsed;// 位图实际使用的颜色表中的颜色数
int ClrImportant;// 位图显示过程中重要的颜色数
BITMAPINFOHEADER;
typedef struct
unsigned short int Signature;
unsigned int Size;
unsigned int Reserved;
unsigned int BitsOffset;
BITMAP_FILEHEADER;
void main()
BITMAP_FILEHEADER head;
BITMAPINFOHEADER bmih;
FILE *fp;
if((fp=fopen("test.bmp","rb"))==NULL)
printf("不能打开该文件\n");
exit(0);
else
fread(&head,14,1,fp);
fread(&bmih,sizeof(bmih),1,fp);
printf("图形高度为%d\n",bmih.height);
printf("图形宽度为%d\n",bmih.width);
fclose(fp);
参考技术B 我只要一个头文件吧。
bmp文件存贮形式为前14个字节为文件信息区,保存的是BMP文件类型标识2,文件长度4,保留字节4,文件描述区长度4,
之后40个字节是图像信息区,为图形尺寸4,图形宽度4,图形高度4,其他就不多说了,你可看下关于BMP文件的说明。
因此读取长宽只要从文件头偏移18字节就行。
#include <stdio.h>
main()
long bmpwidth,bmpheight;
FILE *fp;
fp=fopen("FIVEANGL.bmp","rb");
fseek(fp,18L,SEEK_SET);
fread(&bmpwidth,4,1,fp);
fread(&bmpheight,4,1,fp);
fclose(fp);
printf("\n%s width is %ld,height is %ld","FIVEANGL.bmp",bmpwidth,bmpheight);
getchar();
参考技术C //给你写一个吧
#include<stdio.h>
int main()
int width,height;
FILE* bmpfp = fopen("E:\\风景\\风景1.bmp","rb");
fseek(bmpfp,18,SEEK_SET);
fread(&width,sizeof(int),1,bmpfp);
fread(&height,sizeof(int),1,bmpfp);
printf("width : %d , height : %d\n",width,height);
//运行结果
width : 700 , height : 382本回答被提问者采纳
以上是关于用标准c读取某bmp文件的长宽及象素等信息需要哪些函数?的主要内容,如果未能解决你的问题,请参考以下文章