/**************************************** ********************************** *函数名: * Mosaic(CDC *pDC) * *函数参数: * CDC *pDC-指向设备环境的指针,用于显示位图数据 * *返回值: * 无 * *说明:该函数实现了图像的马赛克显示的效果 ***************************************** *********************************/ void SpecialEffectShow::Mosaik(CDC *pDC) { int bitmapWidth=GetDimensions().cx;//获得源 图像的宽度,以像素为单位 int bitmapHeight=GetDimensions().cy;//获得 源图像的高度,以像素为单位 CRect rect(0,0,bitmapWidth,bitmapHeight);// 以源图像的尺寸创建一个矩形 CBrush brush(RGB(255,255,255)); //设置画刷为白色 pDC->FillRect(&rect,&brush);//将已经显示出来 的原图像重新设置成白色,达到刷新屏幕的效果 LPBITMAPINFO pBitmapInfo=(BITMAPINFO*)m_lpBmpInfoHead; //为适应StretchDIBits函数的需要,将图像信息头 指针强制转换为LPBITMAPINFO类型 //马赛克的大小设置为宽高都是12个像素 int WithFalg=0; //图像宽是12的整数倍的标志 int HeightFlag=0;//图像高是12的整数倍的标志 if((bitmapWidth%12)!=0)WithFalg=1; if((bitmapHeight%12)!=0)HeightFlag=1; long ArrayLength=(bitmapWidth/12+WithFalg) *(bitmapHeight/12+HeightFlag); //将图像宽高都延拓至12的整数倍,然后将图像 分成1212的小块,按行顺序排列成一个数组
struct Square { CPoint pt;//记录每个1212的小块的左上角坐标 bool HitFlag;//当随机扫描所有小块的时候, 记录是否曾经被扫描过 };//自己定义一个结构,由一个Cpoint类型和一个击中标志构成 Square* SquareArray=new Square[ArrayLength]; int x=0; int y=0; for(int i=0; i<ArrayLength; i++) { //初始化每个小块的坐标点 SquareArray[i].pt.x=x; SquareArray[i].pt.y=y; x=x+12; if(x>bitmapWidth) {x=0;y=y+12;} //初始所有小块都未被击中过 SquareArray[i].HitFlag=FALSE; }
long RandNum;//随机变量 srand( (unsigned)time( NULL ) );//生成随机种子 for(i=0;i<=ArrayLength;i++) { do { RandNum=(long)( ( (double)ArrayLength ) *rand()/RAND_MAX );//随机变量在0到ArrayLength-1之间取值 x=SquareArray[RandNum].pt.x; y=SquareArray[RandNum].pt.y; }while(SquareArray[RandNum].HitFlag==TRUE);// 检查小块以前是否被击中过,如果是,重新计算一个随机数 SquareArray[RandNum].HitFlag=TRUE;//设置击中标志 ::StretchDIBits(pDC->GetSafeHdc(), x, y, 12,12, x,bitmapHeight-y-12, 12,12, m_pImgData, pBitmapInfo,DIB_RGB_COLORS, SRCCOPY); Sleep(1);//设置延时时间 } delete [] SquareArray; } |