TVGA全屏幕動畫分析論文

時間:2022-03-20 02:21:00

導語:TVGA全屏幕動畫分析論文一文來源于網友上傳,不代表本站觀點,若需要原創文章可咨詢客服老師,歡迎參考。

TVGA全屏幕動畫分析論文

首先設置tvga卡使其工作在0X5d方式下,屏幕分辨率是640×480×256色。然后重新構造調色板(RemapPalette()),使其適于顯示256灰階的圖像論文。由于TVGA卡的顏色寄存器使用18位存儲模式,即R、G、B分量各占6位,而要顯示灰度圖像R、G、B分量必須賦予相同的值,所以就只能顯示區分26=64灰階的圖像。不過,實驗表明人眼已無法區分64灰階與256灰階圖像的差別。因此,在構造調色板時,0~3索引值對應的R、G、B分量值都為0,4~7索引值對應的R、G、B分量值都為1,…,依次類推,這樣就可以正確顯示一幅256灰階的圖像。

以下是動畫播放序列運動圖像完整的源代碼(AVD.C)。為連續顯示一序列圖像,先將序列圖像的數目(如20)、存放圖像數據文件的路徑(f:\zyf\)、圖像文件的名稱(如z1.img,z2.img,…)錄入一文本文件(如imggroup.lst),運行程序時只需鍵入AVDimggroup.lst即可。源程序中顯示每幅圖像的代碼部分采用嵌入匯編語言編寫,以得到較高的顯示速度。在程序運行過程中,按下空格鍵暫停;連擊空格鍵實現單幀播放;按下任意其它鍵恢復連續播放;按下退出鍵(Escape)退回DOS。在程序設計時,為避免在一個循環結束過渡到下一個循環開始時將要從序列的最后一幅圖像切換到第一幅圖像,因為這時由于圖像運動的不連續性將產生突變,以至屏幕顯示有抖動感或閃爍感,所以筆者采用了第一個循環正向播放,第二個循環反向播放(即正反相間)的方案。如果讀者只希望正向播放,只須刪除源程序中標有“//$$$”的四條語句行即可。

編譯運行環境:本程序用MSC6.0編譯通過,編譯時請使用命令行參數/STACK:20480;圖像數據文件來自大恒公司的VP32圖像采集板(512×512×256灰階)。

#include<graph.h>

#include<stdio.h>

#include<dos.h>

#include<stdlib.h>

#include<string.h>

#include<conio.h>

#include<time.h>

#defineIMGGRP30//ImageNumberinaCycleShowing

#defineESCAPE27//StopShowingandExit

#defineSPACE32//StepShow--HitSpaceBar&OnebyOneShowing

voidRemapPalette(void);

voidmain(intargc,char*argv[])

{

staticchargrpflnm[IMGGRP][80];

charpath[80],flnm[80],bindfn[80],arg[5];

charfnch[2]="\0";

charch-imgnum[5];

inti,i1,i2,i12,ii,imgnum=IMGGRP;

intdispimgs,keyin,StepShow=0;

unsignedshortintVSEG;

unionREGSinregs,outregs;

FILE*fp;

unsignedshortintrow=480,col=512;

unsignedcharfb[512];

intm-b=0;

clock-tcstart,cend;/*Forclock*/

unsignedshortintFH;//FileHandle

printf("\n**********GROUPIMAGESANIMATEDLYSHOWING*********\n");

if(argc>1)

strcpy(flnm,argv[1]);

else

{

printf("\nInputtheImageGroupfilename[.lst]:");

gets(flnm);

}

REDISP:

if(!strchr(flnm,''''.''''))

strcat(flnm,".lst");

if((fp=fopen(flnm,"rt"))==NULL)

{

printf("\nOpenfilefailure!!\a\a\n");

printf("\nPleaseCheckfollowingfileswhetherexist:");

printf("\n%s",flnm);

printf("\n\nNote:Thefileextensionnameisappendedautomatically,");

printf("\nsuchas[.lst]!");

exit(1);

}

inregs.x.ax=0x005d;//SetTVGAMode:640x480x256levels

int86(0x10,&inregs,&outregs);

RemapPalette();//RemapallPalette

cstart=clock();/*Useclockfortimingtohundredthsofseconds*/

strcpy(ch-imgnum,"\0");

for(;;)//Readimagenumberingroup

{

fread(fnch,sizeof(char),1,fp);

if((int)fnch[0]==10)break;

strcat(ch-imgnum,fnch);

}

imgnum=atoi(ch-imgnum);

strcpy(path,"\0");

for(;;)//Readimagepathingroup

{

fread(fnch,sizeof(char),1,fp);

if((int)fnch[0]==10)break;

strcat(path,fnch);

}

for(i=0;i&lt;imgnum;i++)//Readimagenameingroup

{

strcpy(grpflnm[i],"\0");

for(;;)

{

fread(fnch,sizeof(char),1,fp);

if((int)fnch[0]==10)break;

strcat(grpflnm[i],fnch);

}

}

keyin=0;

StepShow=0;//ContinuousShowingdefaultly

dispimgs=0;

i1=0;i2=imgnum-1;i12=1;

for(;;)//SHOWIMAGES--ANTMATEPICTURE[STUDIO]

{//REPEATCYCLEFOREVER

for(i=i1;i<=i2;i+=i12)

{

if(kbhit())

{

keyin=getch();

if(keyin==ESCAPE)gotoCONTINUE;//StopShowingandExit

if(keyin==SPACE)StepShow=1;//StepShow--HitSapceBar

elseStepShow=0;//ContinuousShowing--HitAnyOtherKey

}

if(StepShow==1)

{

keyin=getch();//Standyby

if(keyin==ESCAPE)gotoCONTINUE;

if(keyin!=SPACE)StepShow=0;

}

strcpy(bindfn,path);

strcat(bindfn,grpflnm[i]);

strcpy(flnm,bindfn);

VSEG=0;

-asm

{

MOVAH,3dh;OpenFile

MOVAL,0c0h

LEADX,WORDPTRflnm

INT21h

MOVFH,AX

MOVAX,0a000h

MOVES,AX

XORDI,DI

MOVAX,0eh

MOVDX,3c4h

OUTDX,AL

XORAX,AX

XORAX,02h

MOVDX,3c5h

OUTDX,AL

MOVCX,row

OUTER-CYCLE:

PUSHCX

MOVAH,3fh;ReadFileaLineOnce

MOVBX,FH

MOVCX,col;col=512

LEADX,WORDPTRfb

INT21h

MOVSI,DX

MOVCX,col

INTER-CYCLE:

MOVSB

ORDI,DI

JNZGO-INTER-LOOP

MOVAX,0eh

MOVDX,3c4h

OUTDX,AL

MOVAX,VSEG

INCAX

MOVVSEG,AX

XORAX,02h

MOVDX,3c5h

OUTDX,AL

GO-INTER-LOOP:

LOOPINTER-CYCLE

ADDDI,128;128=640-512

JNCGO-OUTER-LOOP

MOVAX,0eh

MOVDX,3c4h

OUTDX,AL

MOVAX,VSEG

INCAX

MOVVSEG,AX

XORAX,02h

MOVDX,3c5h

OUTDX,AL

GO-OUTER-LOOP:

POPCX

LOOPOUTER-CYCLE

MOVAH,3eh;CloseFile

MOVBX,FH

INT21h

}

dispimgs++;

}

/*Thefollowingline(4sentences)canbeDeletedifwishUp-showingOn

ly

*/

ii=i1;i1=i2;i2=ii;i12*=(-1);//$$$

}

CONTINUE:

cend=clock();

printf("\a");

getch();

fclose(fp);

if(argc>1)gotoENDP;

printf("\nDisplayAnotherImageGroup(Y/[N])?");

gets(arg);

if(!strcmp(arg,"Y")!strcmp(arg,"y"))

{

printf("\nInputimagefilename:");

gets(flnm);

gotoREDISP;

}

ENDP:

-SETVIDEOMODE(-TEXTC80);

printf("Show%5dimages;Spend%4.2fseconds.\n",dispimgs,((float)cend-cst

art)

/CLK-TCK);

}

voidRemapPalette(void)

{

registerinti,j;

unionREGSinregs,outregs;

for(j=0;j<64;i++)//RemapTVGAPalette

for(i=0;i<4;j++)

{

inregs.x.ax=0x1010;

inregs.x.bx=(unsignedchar)(4*i+j);//Indexvalue

inregs.h.ch=(unsignedchar)i;//GreenvalueR,G,B=0-63

inregs.h.cl=(unsignedchar)i;//Bluevalue

inregs.h.dh=(unsignedchar)i;

//Redvalue

int86(0x10,&inregs,&outregs);

}

}

圖像組文件(如imggroup.lst)錄入格式(每項占一行,編輯器用MSC6.0的PWB即可):

3

f:\zyf\

z1.img

z2.img

z3.img

如讀者想進一步提高顯示速度,方案如下:

1.窗口顯示:只顯示感興趣的目標區域;

2.虛擬盤:把序列圖像文件拷貝到虛擬盤(RAMDRIVE)上,文件讀取速度明顯提高;

3.預處理:將序列圖像文件(*.img)的數據順序寫入一個影像文件(如image.mvi)。

4.DMA傳輸:使用DMA管理器直接將數據從RAM區傳送至VRAM區。

筆者已備有位圖(*.bmp)動畫播放程序,以及*.bmp*.img的圖像格式相互轉換程序,愿與愛好圖像處理的朋友們共享!