Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9428169
  • 博文数量: 1227
  • 博客积分: 10026
  • 博客等级: 上将
  • 技术积分: 20273
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-16 12:40
文章分类

全部博文(1227)

文章存档

2010年(1)

2008年(1226)

我的朋友

分类: C/C++

2008-03-12 08:43:37

闪屏的使用在各类软件中很常见,但具有动态效果的却不多见。今天不小心由ACDSee制作的屏保中得到一些灵感并参照了李建湘写的《闪屏图形特技效果的实现》,特提出来与大家探讨,欢迎大家指教。
  其实我的方法也是采用积木法,但是如果使用随机积木法,我们会发现随着划分的块数的增大,执行时间也会随之增大,因此我采用了步长来控制下一点的位置。
  首先,新建的类的框架完全照搬《闪屏图形特技效果的实现》,但删去了其中动态闪屏的具体实现代码,全部换成我自己的。增加了一系列参数。
int m_nBlockNum; //将图片在X,Y方向均分为多少份
int m_nXStep;  //X方向的步长
int m_nYStep;  //Y方向的步长,步长决定了下一点的位置
int m_nDelay;  //绘制完一组点(m_nBlockNum个)后的延时
BOOL m_bDirection; //表示第一个点从何处开始TRUE:左上,FLASE:右下     
  为了加快显示速度,采用一组一组的显示,因此在程序中使用了两种步长,一种是组内步长,一种是组外步长,即使用双重for循环。组内循环很简单,只需显示了每个区域后,x,y方向分别增加对应的步长。
for ( j=0; j= m_nBlockNum )
 {
  x -= m_nBlockNum;
 }
 if ( y >= m_nBlockNum )
 {
  y -= m_nBlockNum;
 }
 dc.StretchBlt( 
  x*stepx, y*stepy, //目标设备逻辑横、纵坐标 
  stepx,stepy, //显示位图的像素宽、高度 
  &MemDC, //位图内存设备对象 
  x*stepx, y*stepy, //位图的起始横、纵坐标 
  stepx,stepy, //位图的像素宽、高度 
  SRCCOPY); 

 x += m_nXStep;
 y += m_nYStep;
}       
  使用步长,那么我们就应该避免“走到”一个已经显示出来的地方,因此组外步长的控制就很重要,我在实际测试中发现组外步长只能取两个值,才能将图片显示完整。
                              可取值           可取值
             (x\y)          0   i+1//x,y分别表示外步长,下同
        0   否  是   
       i+1   是  是  
  造成这种结果,我想应该是算法的原因,如果哪位高手能够找到弥补的方法,请告知一二。
图片的分块由图片尺寸决定,如800 X 600的,如要图片能完全显示出来则不应超过200(能被两个尺寸整除)否则StretchBlt()会“吞噬掉一部分像素”。因为StretchBlt()中的参数类型是int,:)
但是如果增大分块数,则可以使效果更加细腻,则就看个人取决。
(例如当x=0,y=i+1,m_nXStep=1,m_nYStep=200,m_nBlockNum=600时,效果为:1,为图片在垂直方向上三等分,2,至上而下“染色”(恕小弟不知该如何形容,只是看上去象)一次,接着重复步骤2,只是颜色加深,最后再执行一次步骤2,图片完全显示出来)
  P.S.“染色”次数=m_nBlockNum/m_nYStep(或者m_nBlockNum/m_nXStep)
当x=i+1,y=0,m_nXStep=200,m_nYStep=1,m_nBlockNum=600时,效果同上,只是方向由垂直变为水平,但整体效果看上去就象是在打开日本建筑的门!!!大家不妨一试)
瀑布效果:x=0,y=i+1,m_nXStep=1,m_nYStep=20,m_nBlockNum=600,m_nDelay=15,程序运行时,只要视线跟着轨迹动,看上去就象瀑布效果)
很重要的一点:分块数不要超过图片的x,y方向尺寸的任何一个,否则程序会出错。
以下是我已经测试过的效果:
效果比较好的(也是能够显示完整的)
x=0,y=i+1时
m_nXStep=1(或3),m_nYStep=0(至上而下显示)
m_nXStep=1,m_nYStep=m_nBlockNum(至上而下显示)
m_nXStep=1,m_nYStep=1(从中间斜向左下逐渐显示,右上自动跟进)
m_nXStep=1,m_nYStep=2(从水平方向0与1/2处开始向左下显示)
m_nXStep=1,m_nYStep=3(从水平方向0与1/3,2/3处开始向左下显示)
…………(之后效果随着m_nYStep的增大,出现类似锯齿,珊格效果)

以m_nBlockNum的一半为分界点,左右对称,
即是指,m_nXStep=1,m_nYStep=3(向左下)与m_nXStep=1,m_nYStep=m_nBlockNum-3(向右下)效果相同,只是方向左右对称,整体向下的方向不变
x=i+1,y=0时,效果变为x=0,y=i+1时的效果逆时针旋转90度
x=i+1,y=i+1时,特效就很少了,这跟程序的算法有关,:(

能够完全显示的有:
m_nXStep=1,m_nYStep=2
m_nXStep=2,m_nYStep=1
m_nXStep=2,m_nYStep=3
m_nXStep=3,m_nYStep=2
m_nXStep=1,m_nYStep=0(至上而下)
m_nXStep=0,m_nYStep=1(从左到右)

(以下是不完全显示的)强力推荐效果
    x=i+1,y=i+1,m_nXStep=0,m_nYStep=2,m_nBlockNum=600,m_nDelay=10;      
从左到右显示,效果类似半透明窗口,唯一的缺点(?)就是在闪屏下的窗口中的文字有点扭曲,效果如图。


图一 程序效果图

图一:怎么样,是否觉得闪屏下面的文字有点变形了。

或许从某种意义上来讲,也可能是一个好处,至少半透明窗口实现不了这种效果。:)
    x=i+1,y=i+1,m_nXStep=2,m_nYStep=0,m_nBlockNum=600,m_nDelay=10;      
  至上而下,其余同上,之后当固定一个步长为0,另一个不断增大时,效果变为越来越不清晰,因为显示出的像素变少了,最后当某个步长等于m_nBlockNum或0时,就便成了一条线:)
原本想实现一个简单的效果,没想到最后会有那么多效果,至于大家喜欢用哪种,大家自行测试吧。

最后向李建湘致歉,请原谅我直接修改了你的类。

  对了,请教,哪位高手知道渐开线显示效果该如何实现?当然我的水平不高,如有什么地方有误,恳请各位的指正,同时欢迎大家与我交流。
阅读(2070) | 评论(0) | 转发(0) |
0

上一篇:DCT快速变换

下一篇:地图比例尺绘制

给主人留下些什么吧!~~