该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
八.在屏幕上画位图
计算机绘制图像通常采用一种称为位映射图(BITMAP)的图形处理方法进行,位映射图是一个矩形的点阵结构(二维矩阵),显示在屏幕上时,对应屏幕上一个矩形区域,组成位图的数据储存在内存中一段连续的区间。我们比较常见的位图文件有:BMP、PCX、GIF、JPG等。位图通常存储在外部文件中,使用以前必须将其从磁盘文件调入内存。下面介绍将一个256色PCX图形文件读入内存的方法:
1.定义PCX文件头结构:
typedef struct PCX_HEADER
{
char menufactrue; /* 厂家标识编号 0x0a */
char version; /* 文件版本编号 */
char packing_type; /* 压缩模式 */
char bits_per_pixel; /* 每点占用的位数 */
int minx; /* 最小X坐标值 */
int miny; /* 最小Y坐标值 */
int maxx; /* 最大X坐标值 */
int maxy; /* 最大Y坐标值 */
int hres; /* 水平分辨率 */
int vres; /* 垂直分辨率 */
char palette[48]; /* 颜色调色板 */
char unused; /* 未使用 */
char bit_plance; /* 位平面个数 */
int bytes; /* 单一水平线占用的字节数 */
int palette_type; /* 调色板类型 */
char unused2[58]; /* 未使用 */
}PCXHeader,*PCXHeaderPtr;
2.定义用来存放PCX图像数据的结构:
typedef struct PCX_PICTURE
{
int width;
int height;
char far *buffer;
RGBColor palette[256];
}PCXPicture,*PCXPicturePtr;
3.初始化图像数据的函数:
int InitPCX(PCXPicturePtr image,int w,int h)
{
unsigned size=w*h;
image->width=w;
image->height=h;
image->buffer=(char far *)farmalloc(size);
if(image->buffer==NULL) return 0;
return 1;
}
4.从外部文件读入数据的函数:
int LoadPCX(char *filename,PCXPicturePtr image,int flag)
{
FILE *fp;
unsigned num_bytes,count,size;
int index;
unsigned char data;
PCXHeader PcxHeader;
size=image->width*image->height;
if((fp=fopen(filename,"rb"))==NULL)
return 0;
fread(&PcxHeader,sizeof(PCXHeader),1,fp);
count=0;
while(count<=size)
{
data=fgetc(fp);
if(data>=192&&data<=255)
{
num_bytes=data-192;
data=fgetc(fp);
while(num_bytes-->0)
{
*(image->buffer+count)=data;
++count;
}
}
else
{
*(image->buffer+count)=data;
++count;
}
}
fseek(fp,-768L,SEEK_END);
for(index=0;index<256;index++)
{
image->palette[index].red=((fgetc(fp))>>2);
image->palette[index].green=((fgetc(fp))>>2);
image->palette[index].blue=((fgetc(fp))>>2);
}
fclose(fp);
if(flag==1)
for(index=0;index<256;index++)
SetPaletteRegister(index,(RGBColorPtr)&image->palette[index]);
return 1;
}
其中参数flag用来指明调入文件的同时是否设置颜色寄存器(flag=1设置)。
5.画位图的函数:
void DrawImage(int x,int y,int width,int height,char far *image)
{
int i,j;
for(i=0;i
for(j=0;j
{
if(*image!=0&&(x+j)>=0&&(x+j)<320&&(y+i)>=0&&(y+i)<200)
DrawPoint(x+j,y+i,*image);
image++;
}
}
x,y是图像在屏幕上的左上角坐标,width,height是图像的宽度和高度,image是指向内存中图像的指针。
我们对if(*image!=0&&(x+j)>=0&&(x+j)<320&&(y+i)>=0&&(y+i)<200)语句进行一下分析:
*image!=0用来检查所画的颜色值是否是透明色,如果是,则不画出来,这样我们就可以画出有透明效果的图象,即透过图象可以看到背景,透明色通常取值0,也可以用其他的颜色值表示。
(x+j)>=0&&(x+j)<320&&(y+i)>=0&&(y+i)<200语句用来判断所画点的坐标是否超出屏幕显示的范围,这样可以画出具有裁剪效果的图象,如图象的一部份在屏幕外。
这个函数并不是最快的,因为它要执行width X height次判断,更快的函数请看VGA13H函数库中的绘图函数�