圖像漫游論文

時(shí)間:2022-09-17 05:30:00

導(dǎo)語(yǔ):圖像漫游論文一文來(lái)源于網(wǎng)友上傳,不代表本站觀點(diǎn),若需要原創(chuàng)文章可咨詢(xún)客服老師,歡迎參考。

圖像漫游論文

VGA是微機(jī)顯示的廉價(jià)適配器,因而在其上實(shí)現(xiàn)圖形圖像處理的成本較低。在目前國(guó)內(nèi)流行的C語(yǔ)言中,均提供了基本的作圖函數(shù),如BorlandcC++、TurboC和MicrosoftC。但還缺少一個(gè)最基本的圖形圖像處理功能-屏幕漫游功能。本文將討論在VGA16色模式下實(shí)現(xiàn)屏幕圖像漫游的方法,并給出C語(yǔ)言的程序供讀者參考。

一、基本構(gòu)思

為了實(shí)現(xiàn)漫游的功能,首先將想像中的大幅圖像分成N×N塊(每塊應(yīng)小于屏幕的分辨率)相同大小的區(qū)域,然后逐次顯示在屏幕上并存放到一個(gè)文件中。這樣就完成了漫游圖的制作??梢栽O(shè)想,文件提供了一個(gè)無(wú)限分辨率的虛擬屏幕,存儲(chǔ)著大幅圖像數(shù)據(jù)。

在調(diào)用漫游圖時(shí),將存放在文件中的圖像數(shù)據(jù)的一部分顯示在屏幕上,當(dāng)用鍵盤(pán)或鼠標(biāo)控制圖像漫游時(shí),程序首先將屏幕上的圖像移動(dòng)一定的距離,這一過(guò)程實(shí)質(zhì)是硬件漫游。當(dāng)屏幕圖像移動(dòng)后,留出的空白位置則從文件中調(diào)出數(shù)據(jù)顯示到屏幕上,這一步實(shí)質(zhì)為軟件漫游。

二、存圖文件的數(shù)據(jù)結(jié)構(gòu)

假設(shè)在文件ZOOM.SCR中存儲(chǔ)了2×2個(gè)VGA(640×480×16色模式)窗口畫(huà)面,窗口的范圍如圖1所示。其左上角和右下角的坐標(biāo)分別為(XP1,YP1)、(XP2,YP2),將來(lái)就在這一窗口范圍內(nèi)進(jìn)行漫游。

@@T5S11100.GIF;圖1@@

假設(shè)存圖時(shí)每個(gè)窗口大小一樣,高度為d,寬度為w。存圖時(shí)漫游窗口的寬度與起始坐標(biāo)均為8的整數(shù)倍,這樣便于處理。四個(gè)窗口的排號(hào)順序如圖2所示:

@@T5S11101.GIF;圖2@@

在此是實(shí)現(xiàn)2×2畫(huà)面的漫游功能,用戶(hù)可根據(jù)需要實(shí)現(xiàn)n×n個(gè)畫(huà)面的漫游,其方法相同。

三、基本功能函數(shù)

實(shí)現(xiàn)漫游功能主要由以下幾個(gè)函數(shù)實(shí)現(xiàn)

savewin——存圖函數(shù),將屏幕窗口函數(shù)存入文件。

Loadwin——調(diào)圖函數(shù),由文件將圖像數(shù)據(jù)調(diào)入屏幕。

scroll_x——X軸向漫游函數(shù)。

scroll_y——Y軸向漫游函數(shù)。

1.常數(shù)定義及函數(shù)說(shuō)明

/*文件名:scroll.h*+/

#defineXP116/*窗口左上角坐標(biāo)*/

#defineYP132

#defineXP2591/*窗口右下角坐標(biāo)*/

#defineYP2415

#defineLEFT0x4b

#defineRIGHT0x4b

#defineUP0x48

#defineDOWN0x50

#defineINDEXREG10x3CE/*VGA圖形控制器索引寄存器*/

#defineVALREG10x3CF/*VGA圖形控制器數(shù)據(jù)寄存器*/

#defineINDEXREG20x3C4/*VGA定序器索引寄存器*/

#defineVALREG20x3C5/*VGA定序器數(shù)據(jù)寄存器*/

·#defineVGABASE0xA0000000L/*VGA640*48016色模式起始地址*/

voidsavewin(char*,int,int,int,int,int,int);

voidLoadwin(char*,int,int,int,int,int,int,int);

voidscroll_x(int,int,int,int,int);

voidscroll_y(int,int,int,int,int)

2、功能函數(shù)

/*文件名:function.cpp*/

#include<stdio.h

#include<stdlib.h>

#include<conio.h>

#include"scroll.h"

/*制作漫游圖時(shí)存入窗口函數(shù),

fname存放漫游圖文件;

(xleft,ytop)在屏幕上窗口左上角坐標(biāo);

(xright,ybuttom)在屏幕上窗口左上角坐標(biāo);

number圖號(hào)(0-nxy×nxy-1)

nxynxy*nxy拼圖*/

voidsavewin(char*fname,intxleft,intytop,intxright,intybuttom,intnu

mber,intnxy)

{

FILE*fp;

inti,width,height;

registerj,k;

Longtemp,offset,offset1;

charfar*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=(charfar)*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<height;j++){

fseek(fp,offset,SEEK_SET);

fwrite(base,1,width,fp);

offset=offset+(long)(nxy*width);

base=base+80L;

}

}

fclose(fp);

outportb(INDEXREG1,0);

}

/*向屏幕裝入漫游圖窗口函數(shù),

(x0,y0)裝入屏幕起始坐標(biāo);

fname存放漫游圖文件名;

(xleft,ytop)在fname中虛擬窗口左上角坐標(biāo);

(xright,ybuttom)在fname中虛擬窗口右下角坐標(biāo);

nxynxy*nxy拼圖*/

voidLoadwin(char*fname,intxo,inty0,intxleft,intytop,intxright,int

ybuttom,intnxy)

{

FILE*fp;

registerintj,i,n=8,width,height;

charfar*base,*vbase;

registerlongoffset;

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=(charfar*)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<height;j++){

fseek(fp,offset,SEEK_SET);

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-方向漫游函數(shù)

(xleft,ytop,xright,ybuttom)定義漫游窗口;

dy<向上漫游(以象素為單位);

dy>向下漫游(以象素為單位)*/

voidscroll-y(intxleft,intytop,intxright,intybuttom,intdy)

{

intwidth,height,temp;

registeri,j;

charfar*base,far*tbase;

longoffset,toffset;

outportb(INDEXERG1,5);

outportb(VALREG1,1);

width=(xright-xleft+1)/8;

height=ybuttom-ytop+1;

if(dy<0){

base=(charfar*)VGABASE+(long)(ytop*80)+(long)(xleft/8);

tbase=base;

toffset=(long)dy*80L;

temp=height+dy;/*whenmovetoupdy<0*/

for(i=0;i<temp;i++){

for(j=0;j<width;j++){

*base=*(base-toffset);

base++;

}

tbase=tbase+80L;

base=tbase;

}

}

else

{

base=(charfar*)VGABASE+(long)(ybuttom*80)+(long)(xleft/8);

tbase=base;

toffset=(long)dy*80L;

temp=height-dy;/*dy>0*/

for(i=0;i<temp;i++){

for(j=0;j<width;j++){

*base=*(base-toffset);

base++;

}

tbase=tbase-80L;

base=tbase;

}

}

outportb(INDEXREG1,0);

}

/*X-方向漫游函數(shù)

(xleft,ytop,xright,ybuttom)定義漫游窗口;

dx<0向左漫游(以8個(gè)象素為單位);

dx>0向右漫游(以8個(gè)象素為單位)*/

voidscroll-x(intxleft,intytop,intxright,intybuttom,intdx)

{

intwidth,height,temp;

registeri,j;

charfar*base,far*tbase;

longoffset;

outportb(INDEXREG1,5);

outportb(VALREG1,1);

width=(xright-xleft+1)/8;

height=ybuttom-ytop+1;

if(dx<0){

base=(charfar*)VGABASE+(long)(ytop*80)+(long)(xleft/8);

tbase=base;

temp=width+dx;/*whenmovetoleftdx<0*/

for(i=0;i<height;i++){

for(j=0;j<temp;j++){

*base=*(base-dx);

base++;

}

tbase=tbase+80L;

base=tbase;

}

}

else

{

base=(charfar*)VGABASE+(long)(ytop*80)+(long)((xright-7)/8;

tbase=base;

temp=width-dx;/*dx>0*/

for(i=0;i<height;i++){

for(j=0;j<temp;j++){

*base=*(base-dx);

base--;

}

tbase=tbase+80L;

base=tbase;

}

}

outportb(INDEXREG1,0);

}

四、示例

示例exm1.cpp中,首先在虛擬的大幅漫游圖上畫(huà)一個(gè)貫穿整個(gè)漫游圖的“×”,然后按2×2

圖幅存入ZOOM.SCR文件。在示例exm2.cpp中,通過(guò)方向鍵控制圖像漫游。

[程序1]exm1.cpp

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

#include<dos.h>

#include<graphic.h>

#include"scroll.h"

voikdmain(void)

{

FILE*fp;

charch;

charfar*ptr;

intX1,Y1,X2,Y1;

intgdriver=DETECT,gmode;

initgraph(&gdriver,*gmode,"");

setcolor(RED);

line(XP1,YP1,XP2,YP2);

savewin("zoom.scr",XP1,YP1,XP2,YP2,1,2);

cleardevice();

line(XP1,YP1,XP2,YP2);

savewin("zoom.scr",XP1,YP1,XP2,YP2,4,2);

cleardevice();

line(XP2,YP1,XP1,YP2);

savewin("zoom.scr",XP1,YP1,XP2,YP2,2,2);

cleardevice();

line(XP2,YP1,XP1,YP2);

savewin("zoom.scr",XP1,YP1,XP2,YP2,3,2);

closegraph();

}

[程序2]exm2.cpp

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

#include<dos.h>

#include<graphic.h>

#include"scroll.h"

intmdx=0,mdy=0;

voidmain(void)

{

FILE*fp;

charch;

charfar*ptr;

intgdriver=DETECT,gmode;

initgraph(&gdriver,*gmode,"");

/*將存貯在ZOOM.SCR中對(duì)應(yīng)的左上角的部分圖像裝入屏幕窗口*/

loadwin("zoom.scr",xp1,yp1,0,0,XP2-XP1,YP2-YP1,2);

/*以下循環(huán)利用方向鍵控制圖像漫游,“Q”鍵退出*/

do{

ch=getch();

if(ch==0)ch=getch();

if(ch=="Q"||ch=="q")break;

switch(ch){

caseDOWN:/*向下滾動(dòng)64行*/

if(mdy>0){

mdy--;

scroll-y(XP1,YP1,XP2,YP2,64);

loadwin("zoom.scr",XP1,YP1,64*mdx,64*mdy,XP2-XP1+64*mdx,64*(mdy+1)-

1,2)

}

break;

caseUP:/*向上滾動(dòng)64行*/

if(mdy<(YP2-YP1+1)/64){

scroll-y(XP1,YP1,XP2,YP2,-64);

loadwin("zoom.scr",XP1,YP2-63,64*mdx,YP2-YP1+1+64*mdy,XP2-XP1+64*mdx

,YP2-YP1+64*(mdy+1),2);

mdy++;

}

break;

caseLEFT:

if(mdy<(XP2-XP1+1)/64){

scroll-x(XP1,Pp1,XP2,YP2,-8);

loadwin("zoom.scr",XP2-63,YP1,XP2-XP1+1+64*mdx,64*mdy,XP2-XP1+64*(m

dx+1),YP2-YP1+64*mdy,2);

mdx++;

}

break;

caseRIGHT:

if(mdx>0){

mdx--;

scroll-x(XP1,YP1,XP2,YP2,8);

loadwin("zoom.scr",XP1,YP1,64*mdx,64*mdy,64*(mdx+1)-1,YP2-YP1+64*md

y,2);

}

break;

}while(ch!=''''Q'''');

closegraph();