在图像处置责罚领域,当处置责罚或剖析序列运动图像时,需要在屏幕上一连显示这一序列图像(即动画播放),以便视察处置责罚效果或剖析动态信息。日常游戏动画的贪图方式是慢速移动配景和快速改造运动目的(小画面),难以实现全屏动画效果。为此笔者接纳了汇编措辞编程和快速写屏的方式,在通俗的486微机(主频66M,配TVGA9000卡)上达到了每秒显示10幅640×480×256灰阶图像的速度,效果令人写意。
首先设置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),运行法式时只需键入AVD imggroup.lst即可。源法式中显示每幅图像的代码部门接纳嵌入汇编措辞编写,以获得较高的显示速度。在法式运行过程中,按下空格键停歇;连击空格键实现单帧播放;按下尽情其余键规复一连播放;按下退出键(Escape)退回DOS。在法式贪图时,为避免在一个轮回竣事过渡到下一个轮回最先时将要从序列的末尾一幅图像切换到第一幅图像,因为这时因为图像运动的纷歧连性将发生突变,以至屏幕显示有颤栗感或闪灼感,所以笔者接纳了第一个轮回正向播放,第二个轮回反向播放(即正反相间)的方案。若是读者只但愿正向播放,只须删除源法式中标有“//$$$”的四条语句行即可。
编译运行情况:本法式用MS C6.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>
#define IMGGRP 30 //Image Number in a Cycle Showing
#define ESCAPE 27 //Stop Showing and Exit
#define SPACE 32 //Step Show--Hit Space Bar & One by One Showing
void RemapPalette(void);
void main (int argc,char *argv[])
{
static char grpflnm[IMGGRP][80];
char path[80],flnm[80],bindfn[80],arg[5];
char fnch[2]=" ";
char ch-imgnum[5];
int i,i1,i2,i12,ii,imgnum=IMGGRP;
int dispimgs,keyin,StepShow=0;
unsigned short int VSEG;
union REGS inregs,outregs;
FILE *fp;
unsigned short int row=480,col=512;
unsigned char fb[512];
int m-b=0;
clock-t cstart,cend; /* For clock */
unsigned short int FH; // File Handle
printf("n ********** GROUP IMAGES ANIMATEDLY SHOWING ********* n");
if(argc>1)
strcpy(flnm,argv[1]);
else
{
printf("n Input the Image Group file name [.lst]:");
gets(flnm);
}
REDISP:
if(!strchr(flnm,'.'))
strcat(flnm,".lst");
if((fp=fopen(flnm,"rt"))==NULL)
{
printf("n Open file failure!! aan");
printf("n Please Check following files whether exist:");
printf("n%s",flnm);
printf("nn Note:The file extension name is appended automatically,");
printf("n such as [.lst]!");
exit(1);
}
inregs.x.ax=0x005d; // Set TVGA Mode:640x480x256 levels
int86(0x10,&inregs,&outregs);
RemapPalette(); // Remap all Palette
cstart= clock(); /* Use clock for timing to hundredths of seconds */
strcpy(ch-imgnum," ");
for(;;) // Read image number in group
{
fread(fnch,sizeof(char),1,fp);
if((int)fnch[0]==10) break;
strcat(ch-imgnum,fnch);
}
imgnum=atoi(ch-imgnum);
strcpy(path," ");
for(;;) // Read image path in group
{
fread(fnch,sizeof(char),1,fp);
if((int)fnch[0]==10) break;
strcat(path,fnch);
}
for(i=0;i<imgnum;i++) // Read image name in group
{
strcpy(grpflnm[i]," ");
for(;;)
{
fread(fnch,sizeof(char),1,fp);
if((int)fnch[0]==10) break;
strcat (grpflnm[i],fnch);
}
}
keyin=0;
StepShow=0; // Continuous Showing defaultly
dispimgs=0;
i1=0; i2=imgnum-1; i12=1;
for(;;) // SHOW IMAGES--ANTMATE PICTURE [STUDIO]
{// REPEAT CYCLE FOREVER
for(i=i1;i<=i2;i+=i12)
{
if(kbhit())
{
keyin=getch();
if(keyin==ESCAPE) goto CONTINUE; //Stop Showing and Exit
if(keyin==SPACE) StepShow=1; // Step Show--Hit Sapce Bar
else StepShow=0; // Continuous Showing--Hit Any Other Key
}
if(StepShow==1)
{
keyin=getch(); //Standy by
if(keyin==ESCAPE) goto CONTINUE;
if(keyin!=SPACE) StepShow=0;
}
strcpy(bindfn,path);
strcat(bindfn,grpflnm[i]);
strcpy(flnm,bindfn);
VSEG=0;
-asm
{
MOV AH,3dh ;Open File
MOV AL,0c0h
LEA DX,WORD PTR flnm
INT 21h
MOV FH, AX
MOV AX,0a000h
MOV ES,AX
XOR DI,DI
MOV AX,0eh
MOV DX,3c4h
OUT DX,AL
XOR AX,AX
XOR AX,02h
MOV DX,3c5h
OUT DX,AL
MOV CX,row
OUTER-CYCLE:
PUSH CX
MOV AH,3fh ;Read File a Line Once
MOV BX,FH
MOV CX,col ;col=512
LEA DX,WORD PTR fb
INT 21h
MOV SI,DX
MOV CX,col
INTER-CYCLE:
MOVSB
OR DI,DI
JNZ GO-INTER-LOOP
MOV AX,0eh
MOV DX,3c4h
OUT DX,AL
MOV AX,VSEG
INC AX
MOV VSEG,AX
XOR AX, 02h
MOV DX,3c5h
OUT DX,AL
GO-INTER-LOOP:
LOOP INTER-CYCLE
ADD DI,128 ;128=640-512
JNC GO-OUTER-LOOP
MOV AX,0eh
MOV DX,3c4h
OUT DX,AL
MOV AX,VSEG
INC AX
MOV VSEG,AX
XOR AX,02h
MOV DX,3c5h
OUT DX,AL
GO-OUTER-LOOP:
POP CX
LOOP OUTER-CYCLE
MOV AH,3eh ;Close File
MOV BX,FH
INT 21h
}
dispimgs++;
}
/* The following line (4 sentences) can be Deleted if wish Up-showing On
ly
*/
ii=i1; i1=i2; i2=ii; i12*=(-1); //$$$
}
CONTINUE:
cend=clock();
printf("a");
getch();
fclose(fp);
if(argc>1) goto ENDP;
printf("n Display Another Image Group(Y/[N])?");
gets(arg);
if(!strcmp(arg,"Y")||!strcmp(arg,"y"))
{
printf("n Input image file name:");
gets(flnm);
goto REDISP;
}
ENDP:
-SETVIDEOMODE(-TEXTC80);
printf(" Show %5d images;Spend %4.2f seconds.n",dispimgs,((float)cend-cst
art)
/CLK-TCK);
}
void RemapPalette(void)
{
register int i,j;
union REGS inregs,outregs;
for(j=0;j<64;i++) //Remap TVGA Palette
for(i=0;i<4;j++)
{
inregs.x.ax=0x1010;
inregs.x.bx=(unsigned char)(4*i+j); //Index value
inregs.h.ch=(unsigned char)i; //Green value R,G,B=0-63
inregs.h.cl=(unsigned char)i; //Blue value
inregs.h.dh=(unsigned char)i;
//Red value
int86(0x10,&inregs,&outregs);
}