日期:2023-01-24 阅读量:0次 所属栏目:计算机应用
vga是微机显示的廉价适配器,因而在其上实现图形图像处理的成本较低。在目前国内流行的c语言中,均提供了基本的作图函数,如borlandc c++、turbo c和microsoftc。但还缺少一个最基本的图形图像处理功能-屏幕漫游功能。本文将讨论在vga16色模式下实现屏幕图像漫游的方法,并给出c语言的程序供读者参考。
一、基本构思
为了实现漫游的功能,首先将想像中的大幅图像分成n×n块(每块应小于屏幕的分辨率)相同大小的区域,然后逐次显示在屏幕上并存放到一个文件中。这样就完成了漫游图的制作。可以设想,文件提供了一个无限分辨率的虚拟屏幕,存储着大幅图像数据。
在调用漫游图时,将存放在文件中的图像数据的一部分显示在屏幕上,当用键盘或鼠标控制图像漫游时,程序首先将屏幕上的图像移动一定的距离,这一过程实质是硬件漫游。当屏幕图像移动后,留出的空白位置则从文件中调出数据显示到屏幕上,这一步实质为软件漫游。
二、存图文件的数据结构
假设在文件中存储了2×2个vga(640×480×16色模式)窗口画面,窗口的范围如图1所示。其左上角和右下角的坐标分别为(xp1,yp1)、(xp2,yp2),将来就在这一窗口范围内进行漫游。
@@;图1@@
假设存图时每个窗口大小一样,高度为d,宽度为w。存图时漫游窗口的宽度与起始坐标均为8的整数倍,这样便于处理。四个窗口的排号顺序如图2所示:
@@;图2@@
在此是实现2×2画面的漫游功能,用户可根据需要实现n×n个画面的漫游,其方法相同。
三、基本功能函数
实现漫游功能主要由以下几个函数实现
savewin——存图函数,将屏幕窗口函数存入文件。
loadwin——调图函数,由文件将图像数据调入屏幕。
scroll_x——x轴向漫游函数。
scroll_y——y轴向漫游函数。
1.常数定义及函数说明
/*文件名:scroll.h*+/
# define xp1 16 /* 窗口左上角坐标 */
# define yp1 32
# define xp2 591 /* 窗口右下角坐标*/
# define yp2 415
# define left 0x4b
# define right 0x4b
# define up 0x48
# define down 0x50
# define indexreg1 0x3ce /* vga图形控制器索引寄存器 */
# define valreg1 0x3cf /* vga图形控制器数据寄存器 */
# define indexreg2 0x3c4 /* vga定序器索引寄存器*/
# define valreg2 0x3c5 /* vga定序器数据寄存器 */
·# define vgabase 0xa0000000l /* vga 640*480 16色模式起始地址 */
void savewin (char *,int,int,int,int,int,int);
void loadwin (char *,int,int,int,int,int,int,int);
void scroll_x (int,int,int,int,int);
void scroll_y (int,int,int,int,int)
2、功能函数
/* 文件名:*/
# include
# include
# include "scroll.h"
/*制作漫游图时存入窗口函数,
fname存放漫游图文件;
(xleft,ytop)在屏幕上窗口左上角坐标;
(xright,ybuttom)在屏幕上窗口左上角坐标;
number图号(0-nxy×nxy-1)
nxy nxy*nxy拼图*/
void savewin(char *fname,int xleft,int ytop,int xright,int ybuttom,int nu
mber,int nxy)
{
file *fp;
int i,width,height;
register j,k;
long temp,offset,offset1;
char far *base;
width=(xright-xleft+1)/8;
height=ybuttom-ytop+1;
fp=fopen(fname,"rb+");
offset=(long)(number-number%nxy)*(long)width*(long)height;
offset1=offset;
for(i=0;i<4;i++) {
outportb(indexreg1,4);
outportb(valreg1,i);
base=(char far)*vgabase+(long)(ytop*80)+(long)(xleft/8);
offset=(long)(i*nxy*nxy)*(long)width*(long)height+(long)(number%nxy)*(l
ong)width+offset1;
for(j=0;j
fwrite(base,1,width,fp);
offset=offset+(long)(nxy*width);
base=base+80l;
}
}
fclose(fp);
outportb(indexreg1,0);
}
/* 向屏幕装入漫游图窗口函数,
(x0,y0)装入屏幕起始坐标;
fname存放漫游图文件名;
(xleft,ytop)在fname中虚拟窗口左上角坐标;
(xright,ybuttom)在fname中虚拟窗口右下角坐标;
nxynxy*nxy拼图*/
void loadwin(char *fname,int xo,int y0,int xleft,int ytop,int xright,int
ybuttom,int nxy)
{
file *fp;
register int j,i,n=8,width, height;
char far *base,*vbase;
register long offset;
fp=fopen(fname,"rb");
width=(xright-xleft+1)/8;
height=ybuttom-ytop+1;
for(i=3;i>0;i--) {
outportb(indexreg1,5);
outportb(valreg1,0);
outportb(indexreg2,2);
outportb(valreg2,n);
base=(char far*)vgabase+(long)y0×80l+(long)(x0/8);
offset=(long)(i*nxy*nxy)*(long)(yp2-yp1+1)*(long)((xp2-xp1+1)/8)+(long)(x
left/8)+(long)(ytop*nxy)*(long)((xp2-xp1+1)/8);
for(j=0;j
fread(base,1,width,fp);
offset=offset+(long)nxy*(long)((xp2-xp1+1)/8);
base=base+80l;
}
n=n/2;
}
fclose(fp);
outportb(valreg2,oxff);
outportb(indexreg2,oxf);
outportb(indexreg1,0);
}
/* y-方向漫游函数
(xleft,ytop,xright,ybuttom)定义漫游窗口;
dy<向上漫游(以象素为单位);
dy>向下漫游(以象素为单位)*/
void scroll-y(int xleft,int ytop,int xright,int ybuttom,int dy)
{
int width,height,temp;
register i,j;
char far *base,far *tbase;
long offset,toffset;
outportb(indexerg1,5);
outportb(valreg1,1);
width=(xright-xleft+1)/8;
height=ybuttom-ytop+1;
if(dy<0){
base=(char far *)vgabase+(long)(ytop*80)+(long)(xleft/8);