我想问一下,C++怎么调用图片
头文件bitmap.h
/*
OpenGL的Windows BMP文件定义。
*
*作者迈克尔·斯威特。
*/
#ifndef _BITMAP_H_
# define _BITMAP_H_
/*
*包括必要的标题。
*/
# include & ltGL/glut . h & gt;
# ifdef WIN32
# include & ltwindows.h & gt
# include & ltwingdi.h & gt
# endif /* WIN32 */
/*
*使这个头文件与C和C++源代码一起工作...
*/
# ifdef __cplusplus
外部" C" {
# endif /* __cplusplus */
/*
*位图文件数据结构(这些在& ltwingdi.h & gt下面的
* Windows...)
*
*请注意,大多数Windows编译器会打包以下结构,因此
*在MacOS或UNIX下读取它们时,我们需要读取单个字段
*为了避免对齐上的差异...
*/
# ifndef WIN32
typedef struct /**** BMP文件头结构****/
{
无符号短bfType/*文件的幻数*/
无符号int bfSize/*文件大小*/
无符号短整型bfreserved 1;/*保留*/
无符号短整型bfReserved2/* ...*/
无符号int bfOffBits/*位图数据的偏移量*/
} BITMAPFILEHEADER
# define BF_TYPE 0x4D42 /* "MB" */
typedef struct /**** BMP文件信息结构****/
{
无符号int biSize/*信息标题的大小*/
int双宽度;/*图像的宽度*/
int biHeight/*图像的高度*/
无符号短双翼机;/*颜色平面的数量*/
无符号短biBitCount/*每个像素的位数*/
无符号整数双压缩;/*要使用的压缩类型*/
无符号int biSizeImage/*图像数据的大小*/
int biXPelsPerMeter/*每米X像素*/
int biYPelsPerMeter/*每米Y像素*/
无符号int biClrUsed/*使用的颜色数量*/
无符号int biClrImportant/*重要颜色的数量*/
} BITMAPINFOHEADER
/*
*双压缩字段的常数...
*/
# define BI_RGB 0 /*无压缩-直接BGR数据*/
# define BI_RLE8 1 /* 8位游程压缩*/
# define BI_RLE4 2 /* 4位游程长度压缩*/
#用RGB遮罩定义BI_BITFIELDS 3 /* RGB位图*/
typedef struct /****色彩映射表条目结构****/
{
无符号字符rgbBlue/*蓝色值*/
无符号字符rgbGreen/*绿色值*/
无符号字符rgbRed/*红色值*/
无符号字符rgbReserved/*保留*/
} RGBQUAD
typedef struct /****位图信息结构****/
{
BITMAPINFOHEADER bmiHeader/*图像标题*/
RGBQUAD BMI colors[256];/*图像色彩映射表*/
} BITMAPINFO
# endif /*!WIN32 */
/*
*原型...
*/
extern Glu byte * LoadDIBitmap(const char * filename,BITMAPINFO * * info);
extern int SaveDIBitmap(const char * filename,BITMAPINFO *info,
GLubyte *位);
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /*!_BITMAP_H_ */
源文件bitmap.c
/*
*用于OpenGL的Windows BMP文件函数。
*
*作者迈克尔·斯威特。
*/
#包含" bitmap.h "
# include & ltstdio.h & gt
# include & ltstdlib.h & gt
# include & lt错误号& gt
#ifdef WIN32
/*
* 'LoadDIBitmap()' -从磁盘加载DIB/BMP文件。
*
*如果成功,返回指向位图的指针,否则返回NULL...
*/
GLubyte * /* O -位图数据* /
LoadDIBitmap(const char * filename,/* I -要加载的文件*/
BITMAPINFO **info) /* O -位图信息*/
{
FILE * fp/*打开文件指针*/
GLubyte *位;/*位图像素位数*/
int bitsize/*位图的大小*/
int infosize/*标题信息的大小*/
BITMAPFILEHEADER标头;/*文件头*/
/*尝试打开文件;使用“rb”模式读取这个*二进制*文件。*/
if ((fp = fopen(文件名,“Rb”))= = NULL)
返回(NULL);
/*读取文件头和任何后续位图信息...*/
if(fread(& amp;header,sizeof(BITMAPFILEHEADER),1,FP)& lt;1)
{
/*无法读取文件头-返回NULL...*/
fclose(FP);
返回(NULL);
}
if (header.bfType!= 'MB') /*检查BM是否反转...*/
{
/*不是位图文件-返回空值...*/
fclose(FP);
返回(NULL);
}
infosize = header . bfoff bits-sizeof(bitmapfile header);
if((* info =(BITMAPINFO *)malloc(infosize))= = NULL)
{
/*无法为位图信息分配内存-返回空值...*/
fclose(FP);
返回(NULL);
}
if (fread(*info,1,infosize,FP)& lt;infosize)
{
/*无法读取位图头-返回空值...*/
免费(* info);
fclose(FP);
返回(NULL);
}
/*现在我们已经读入了所有的头信息,为*分配内存
*位图并读入*它*...*/
if((bitsize =(* info)-& gt;bmiHeader.biSizeImage) == 0)
bitsize =(* info)-& gt;bmiHeader.biWidth *
(*信息)-& gt;bmiHeader.biBitCount + 7) / 8 *
ABS((* info)-& gt;BMI header . BIH height);
if((bits = malloc(bitsize))= = NULL)
{
/*无法分配内存-返回NULL!*/
免费(* info);
fclose(FP);
返回(NULL);
}
if (fread(bits,1,bitsize,FP)& lt;比特大小)
{
/*无法读取位图空闲内存并返回NULL!*/
免费(* info);
免费(位);
fclose(FP);
返回(NULL);
}
/*好了,一切正常——返回分配的位图...*/
fclose(FP);
返回(位);
}
/*
* 'SaveDIBitmap()' -将DIB/BMP文件保存到磁盘。
*
*成功时返回0,失败时返回-1...
*/
int /* O - 0 =成功,-1 =失败*/
SaveDIBitmap(const char * filename,/* I -要加载的文件*/
BITMAPINFO *info,/* I -位图信息*/
GLubyte *bits) /* I -位图数据*/
{
FILE * fp/*打开文件指针*/
int size,/*文件大小*/
infosize,/*位图信息的大小*/
bitsize/*位图像素的大小*/
BITMAPFILEHEADER标头;/*文件头*/
/*尝试打开文件;用“wb”模式写这个*二进制*文件。*/
if ((fp = fopen(文件名,“WB”))= = NULL)
return(-1);
/*算出位图大小*/
if(info-& gt;bmiHeader.biSizeImage == 0)
bitsize =(info-& gt;bmiHeader.biWidth *
信息-& gt;bmiHeader.biBitCount + 7) / 8 *
abs(信息-& gt;BMI header . BIH height);
其他
bitsize = info-& gt;BMI header . bisize image;
/*算出页眉尺寸*/
infosize = sizeof(BITMAPINFOHEADER);
开关(信息->;bmiHeader.biCompression)
{
案例BI _位字段:
infosize+= 12;/*添加3个RGB双字掩码*/
if(info-& gt;bmiHeader.biClrUsed == 0)
打破;
案例BI_RGB:
if(info-& gt;bmiHeader.biBitCount & gt8 & amp& amp
信息-& gt;bmiHeader.biClrUsed == 0)
打破;
案例BI_RLE8:
案例BI_RLE4:
if(info-& gt;bmiHeader.biClrUsed == 0)
infosize+=(1 & lt;& lt信息-& gt;BMI header . bibitcount)* 4;
其他
infosize+= info-& gt;BMI header . biclrsered * 4;
打破;
}
size = sizeof(bitmapfile header)+infosize+bitsize;
/*写入文件头、位图信息和位图像素数据...*/
header.bfType = ' MB/*非便携式...叹息*/
header.bfSize = size
header . bfreserved 1 = 0;
header . BF reserved 2 = 0;
header . bfoff bits = sizeof(bitmapfile header)+infosize;
if(fwrite(& amp;header,1,sizeof(BITMAPFILEHEADER),FP)& lt;sizeof(BITMAPFILEHEADER))
{
/*无法写入文件头-返回...*/
fclose(FP);
return(-1);
}
if (fwrite(info,1,infosize,FP)& lt;infosize)
{
/*无法写入位图头-返回...*/
fclose(FP);
return(-1);
}
if (fwrite(bits,1,bitsize,FP)& lt;比特大小)
{
/*无法写入位图-返回...*/
fclose(FP);
return(-1);
}
/*好的,一切都很好——返回...*/
fclose(FP);
return(0);
}
#else /*!WIN32 */
/*
*用于读写16位和32位小端整数的函数。
*/
静态无符号短read _ word(FILE * FP);
静态无符号int read _ dword(FILE * FP);
static int read _ long(FILE * FP);
静态int write_word(FILE *fp,无符号short w);
静态int write_dword(FILE *fp,unsigned int dw);
static int write_long(FILE *fp,int l);
/*
* 'LoadDIBitmap()' -从磁盘加载DIB/BMP文件。
*
*如果成功,返回指向位图的指针,否则返回NULL...
*/
GLubyte * /* O -位图数据* /
LoadDIBitmap(const char * filename,/* I -要加载的文件*/
BITMAPINFO **info) /* O -位图信息*/
{
FILE * fp/*打开文件指针*/
GLubyte *位;/*位图像素位数*/
GLubyte * ptr/*指向位图的指针*/
GLubyte温度;/*用于交换红色和蓝色的临时变量*/
int x,y;/*图像中的X和Y位置*/
int长度;/*线路长度*/
int bitsize/*位图的大小*/
int infosize/*标题信息的大小*/
BITMAPFILEHEADER标头;/*文件头*/
/*尝试打开文件;使用“rb”模式读取这个*二进制*文件。*/
if ((fp = fopen(文件名,“Rb”))= = NULL)
返回(NULL);
/*读取文件头和任何后续位图信息...*/
header . BF type = read _ word(FP);
header . bfsize = read _ dword(FP);
header . bfreserved 1 = read _ word(FP);
header . bfreserved 2 = read _ word(FP);
header . bfoff bits = read _ dword(FP);
if (header.bfType!= BF_TYPE) /*检查BM是否反转...*/
{
/*不是位图文件-返回空值...*/
fclose(FP);
返回(NULL);
}
infosize = header . bfoffbits-18;
if((* info =(BITMAPINFO *)malloc(sizeof(BITMAPINFO)))= = NULL)
{
/*无法为位图信息分配内存-返回空值...*/
fclose(FP);
返回(NULL);
}
(*信息)-& gt;BMI header . bisize = read _ dword(FP);
(*信息)-& gt;BMI header . bi width = read _ long(FP);
(*信息)-& gt;BMI header . BIH height = read _ long(FP);
(*信息)-& gt;BMI header . bi planes = read _ word(FP);
(*信息)-& gt;BMI header . bibitcount = read _ word(FP);
(*信息)-& gt;BMI header . bi compression = read _ dword(FP);
(*信息)-& gt;BMI header . bisize image = read _ dword(FP);
(*信息)-& gt;BMI header . bixpelspermeter = read _ long(FP);
(*信息)-& gt;BMI header . biypelspermeter = read _ long(FP);
(*信息)-& gt;BMI header . biclrsered = read _ dword(FP);
(*信息)-& gt;BMI header . biclr important = read _ dword(FP);
if(infosize & gt;40)
if(fread(* info)-& gt;bmiColors,infosize - 40,1,FP)& lt;1)
{
/*无法读取位图头-返回空值...*/
免费(* info);
fclose(FP);
返回(NULL);
}
/*现在我们已经读入了所有的头信息,为*分配内存
*位图并读入*它*...*/
if((bitsize =(* info)-& gt;bmiHeader.biSizeImage) == 0)
bitsize =(* info)-& gt;bmiHeader.biWidth *
(*信息)-& gt;bmiHeader.biBitCount + 7) / 8 *
ABS((* info)-& gt;BMI header . BIH height);
if((bits = malloc(bitsize))= = NULL)
{
/*无法分配内存-返回NULL!*/
免费(* info);
fclose(FP);
返回(NULL);
}
if (fread(bits,1,bitsize,FP)& lt;比特大小)
{
/*无法读取位图空闲内存并返回NULL!*/
免费(* info);
免费(位);
fclose(FP);
返回(NULL);
}
/*交换红色和蓝色*/
length =(* info)-& gt;BMI header . bi width * 3+3)& amp;~3;
for(y = 0;y & lt(*信息)-& gt;BMI header . BIH height;y ++)
for (ptr =位+ y *长度,x =(*信息)-& gt;BMI header . bi width;
x & gt0;
x -,ptr += 3)
{
temp = ptr[0];
ptr[0]= ptr[2];
ptr[2]= temp;
}
/*好了,一切正常——返回分配的位图...*/
fclose(FP);
返回(位);
}
/*
* 'SaveDIBitmap()' -将DIB/BMP文件保存到磁盘。
*
*成功时返回0,失败时返回-1...
*/
int /* O - 0 =成功,-1 =失败*/
SaveDIBitmap(const char * filename,/* I -要加载的文件*/
BITMAPINFO *info,/* I -位图信息*/
GLubyte *bits) /* I -位图数据*/
{
FILE * fp/*打开文件指针*/
int size,/*文件大小*/
infosize,/*位图信息的大小*/
bitsize/*位图像素的大小*/
/*尝试打开文件;用“wb”模式写这个*二进制*文件。*/
if ((fp = fopen(文件名,“WB”))= = NULL)
return(-1);
/*算出位图大小*/
if(info-& gt;bmiHeader.biSizeImage == 0)
bitsize =(info-& gt;bmiHeader.biWidth *
信息-& gt;bmiHeader.biBitCount + 7) / 8 *
abs(信息-& gt;BMI header . BIH height);
其他
bitsize = info-& gt;BMI header . bisize image;
/*算出页眉尺寸*/
infosize = sizeof(BITMAPINFOHEADER);
开关(信息->;bmiHeader.biCompression)
{
案例BI _位字段:
infosize+= 12;/*添加3个RGB双字掩码*/
if(info-& gt;bmiHeader.biClrUsed == 0)
打破;
案例BI_RGB:
if(info-& gt;bmiHeader.biBitCount & gt8 & amp& amp
信息-& gt;bmiHeader.biClrUsed == 0)
打破;
案例BI_RLE8:
案例BI_RLE4:
if(info-& gt;bmiHeader.biClrUsed == 0)
infosize+=(1 & lt;& lt信息-& gt;BMI header . bibitcount)* 4;
其他
infosize+= info-& gt;BMI header . biclrsered * 4;
打破;
}
size = sizeof(bitmapfile header)+infosize+bitsize;
/*写入文件头、位图信息和位图像素数据...*/
write_word(fp,BF _ TYPE);/* bfType */
write_dword(fp,size);/* bfSize */
write_word(fp,0);/* bfReserved1 */
write_word(fp,0);/* bfReserved2 */
write_dword(fp,18+infosize);/* bfOffBits */
write_dword(fp,info-& gt;BMI header . bisize);
write_long(fp,info-& gt;BMI header . bi width);
write_long(fp,info-& gt;BMI header . BIH height);
write_word(fp,info-& gt;BMI header . biplanes);
write_word(fp,info-& gt;BMI header . bibitcount);
write_dword(fp,info-& gt;BMI header . bi compression);
write_dword(fp,info-& gt;BMI header . bisize image);
write_long(fp,info-& gt;BMI header . bixpelspermeter);
write_long(fp,info-& gt;BMI header . biypelspermeter);
write_dword(fp,info-& gt;BMI header . biclrused);
write_dword(fp,info-& gt;BMI header . biclr important);
if(infosize & gt;40)
if(fwrite(info-& gt;bmiColors,infosize - 40,1,FP)& lt;1)
{
/*无法写入位图头-返回...*/
fclose(FP);
return(-1);
}
if (fwrite(bits,1,bitsize,FP)& lt;比特大小)
{
/*无法写入位图-返回...*/
fclose(FP);
return(-1);
}
/*好的,一切都很好——返回...*/
fclose(FP);
return(0);
}
/*
* 'read_word()' -读取16位无符号整数。
*/
静态无符号短整型/* O - 16位无符号整数*/
read_word(FILE *fp) /* I -要从中读取的文件*/
{
无符号字符b0,b 1;/*来自文件的字节*/
B0 = getc(FP);
b 1 = getc(FP);
return((b 1 & lt;& lt8)| B0);
}
/*
* 'read_dword()' -读取32位无符号整数。
*/
静态无符号整数/* O - 32位无符号整数*/
read_dword(FILE *fp) /* I -要从中读取的文件*/
{
无符号字符b0,b1,b2,B3;/*来自文件的字节*/
B0 = getc(FP);
b 1 = getc(FP);
B2 = getc(FP);
B3 = getc(FP);
return((((((B3 & lt;& lt8)| B2)& lt;& lt8)| b 1)& lt;& lt8)| B0);
}
/*
* 'read_long()' -读取32位有符号整数。
*/
static int /* O - 32位有符号整数*/
read_long(FILE *fp) /* I -要从中读取的文件*/
{
无符号字符b0,b1,b2,B3;/*来自文件的字节*/
B0 = getc(FP);
b 1 = getc(FP);
B2 = getc(FP);
B3 = getc(FP);
return((int)((((B3 & lt;& lt8)| B2)& lt;& lt8)| b 1)& lt;& lt8)| B0);
}
/*
* 'write_word()' -写入一个16位无符号整数。
*/
成功时为静态int /* O - 0,错误时为-1 */
write_word(FILE *fp,/* I -要写入的文件*/
无符号短整型w) /* I -要写入的整数*/
{
putc(w,FP);
return(putc(w & gt;& gt8,FP));
}
/*
* 'write_dword()' -写入一个32位无符号整数。
*/
成功时为静态int /* O - 0,错误时为-1 */
write_dword(FILE *fp,/* I -要写入的文件*/
unsigned int dw) /* I -要写入的整数*/
{
putc(dw,FP);
putc(dw & gt;& gt8、FP);
putc(dw & gt;& gt16,FP);
return(putc(dw & gt;& gt24,FP));
}
/*
* 'write_long()' -写入一个32位有符号整数。
*/
成功时为静态int /* O - 0,错误时为-1 */
write_long(FILE *fp,/* I -要写入的文件*/
int l) /* I -要写入的整数*/
{
putc(l,FP);
putc(l & gt;& gt8、FP);
putc(l & gt;& gt16,FP);
return(putc(l & gt;& gt24,FP));
}
#endif /* WIN32 */