圖像漫游論文
時(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();
熱門(mén)標(biāo)簽
圖像時(shí)代 圖像設(shè)計(jì)論文 圖像法論文 圖像處理 圖像專(zhuān)業(yè)論文 心理培訓(xùn) 人文科學(xué)概論