3.栅条显示特效
栅条特效是移动特效的复杂组合,可以分为垂直栅条和水平栅条两类。它的基本思想是将图像分为垂直或水平的的小条,奇数条向上或向左显示/清除,偶数条向下或向右显示/清除。当然也可以规定进行相反的方向显示/清除。下面的代码是实现垂直栅条的例子:
………………………………… int m=8; for(int i=0;i<=lpDIBHdr->biHeight;i++) for(int j=0;j<=lpDIBHdr->biWidth;j+=m) {//向下显示偶数条; StretchDIBits (hDC,j,0,m,i,j,lpDIBHdr->biHeight-i, m,i, lpDIBBits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);//juanlianxiaoguo j=j+m; //向上显示奇数条; StretchDIBits (hDC,j,lpDIBHdr->biHeight-i,m,i,j,0, m,i, lpDIBBits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);// DelayTime(20); }………………………………… |
4.马赛克效果
马赛克显示是指图像被分成许多的小块,它们以随机的次序显示出来,直到图像显示完毕。实现马赛克的效果主要解决的问题是如何定义显示随机序列的小方块,这个问题的解决可以在定义过小方块的基础上,用一个数组来记录各个方块的左上角的坐标的位置。显示图像过程中,产生一个随机数来挑选即将显示的小方块,显示后将该方块的位置坐标从数组中剔除。清除过程与之相仿。剔除显示过的方块的位置坐标的方法是将该数组中的最后的一个点的坐标拷贝到当前位置,然后删除数组中的最后点的坐标,经过实现发现这样处理有时显示的图像是不完整的,分析其原因是生成随机数的过程有舍入溢出误差。读者可以采用其它的办法解决这个问题,例如可以生成固定的随机数组或采用一个动态的数组来跟踪未显示的图像方块的坐标等方法。
………………………………… int m,n; int RectSize=60;//方块的宽、高尺寸为60个像素; if(lpDIBHdr->biWidth%RectSize!=0)//得到图像水平方块的个数; m= lpDIBHdr->biWidth/RectSize+1; else m= lpDIBHdr->biWidth/RectSize; if(lpDIBHdr->biHeight%RectSize!=0)//得到图像垂直方块的个数; n= lpDIBHdr->biHeight/RectSize+1; else n=lpDIBHdr->biHeight/RectSize; POINT *point=new POINT[n*m];//申请一个数组用来记录各个方块的左上角的坐标; POINT point1; for(int a=0;a<m;a++)//将各个方块的左上角的坐标记录到数组中; for(int b=0;b<n;b++) { point1.x=a*RectSize; point1.y=b*RectSize; *(point+a*b+b)=point1; } //开始随机的显示各个小方块; double fMax=RAND_MAX;//定义Rand()函数的最大值; for(int k=m*n-1;k>=0;k--) { int c=(int)((double)(m*n)*rand()/fMax); int mx=point[c].x; int my=point[c].y; //显示对应的图像的小块; StretchDIBits (hDC,mx,my,RectSize,RectSize, mx,lpDIBHdr->biHeight-my,RectSize,RectSize, lpDIBBits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY); point[c].x=point[k].x; point[c].y=point[k].y; DelayTime(50); } ………………………………… |
5.图像的淡入淡出效果
图像的淡入淡出的显示效果被广泛的应用在多媒体娱乐软件中,是一种特别重要的特效显示方法。淡入就是将显示图像的目标区域由本色逐渐过度的图像中的各个像素点的颜色;淡出就是由显示的图像逐渐过度到目标区域的本色。实现图像的淡入淡出有两种办法:一是均匀的改变图像的调色板中的颜色索引值;另一种方法是改变图像像素的灰度值。第一种方法实现起来比较繁琐,第二种方法就比较简单。下面是我们采用第二种方法实现图像淡入效果的代码:
………………………………… //申请一个与图像缓冲区相同大小的内存; hdibcopy=(HDIB)GlobalAlloc(GMEM_SHARE,lpDIBHdr->biWidth*lpDIBHdr->biHeight); lpbits=(BYTE*)GlobalLock(hdibcopy); //将缓冲区的数据初始化; for(int k=0;k<lpDIBHdr->biWidth*lpDIBHdr->biHeight;k++) { *(lpbits+k)=(BYTE)255; } //显示最初的图像为“白色” StretchDIBits (hDC,0,0,lpDIBHdr->biWidth,lpDIBHdr->biHeight,0,0, lpDIBHdr->biWidth,lpDIBHdr->biHeight, lpbits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY); //布尔变量end用来标志何时淡入处理结束; BOOL end=false; while(!end) { int a=0; for(int k=0;k<lpDIBHdr->biWidth*lpDIBHdr->biHeight;k++) { //判断是否待显示的像素的灰度值已经小于原始图像对应点的灰度值,如是则计数; if(*(lpbits+k)<*(lpDIBBits+k)) a++; else//否则对应点的灰度值继续减少; *(lpbits+k)-=(BYTE)10; } //显示处理后的图像数据lpbits; StretchDIBits (hDC,0,0,lpDIBHdr->biWidth,lpDIBHdr->biHeight,0,0, lpDIBHdr->biWidth,lpDIBHdr->biHeight, lpbits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY); //如果所有的点的灰度值的都小于或等于原始图像的像素点的灰度值,则认为图像的淡入处理结束。 if(a==lpDIBHdr->biWidth*lpDIBHdr->biHeight) end=true; DelayTime(50); ………………………………… |
本文上面的内容介绍了几种图像的特殊显示效果,代码在Windows2000和Visual C++(www.cppentry.com)6.0编程(www.cppentry.com)环境下编译通过,运行正常,处理达到了预期的效果。读者可以将上面介绍的显示图像的函数和处理思路结合起来,实现更多效果。 |