GDI实现图像的简单显示特效

1. 原理                                                                                                                                                  
    核心是将图像分成不同的块,然后以不同的顺序显示

2. 特效                                                                                                                    
    要实现图片的特效,首先加载一副位图
	//
	//加载位图

	CDC memDC;
	memDC.CreateCompatibleDC(pDC);	//创建兼容DC

	HBITMAP	hBmp;					//加载位图
	hBmp = (HBITMAP)LoadImageW(NULL,L"1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);

	BITMAP bm;						//获取位图信息
	GetObject(hBmp,sizeof(bm),&bm);

	SelectObject(memDC,hBmp);		//位图选入内存DC
    要显示特效,还需获得显示屏幕的DC
    可以在MFC 单文档程序的OnDraw 中实现特效的绘制,其屏幕DC 为 pDC

2.1  逐行显示特效
    方法:循环,每次显示一行
	//逐行显示特效
	int offset_x = 10;
	int offset_y = 10;
	for(int i=0;i<bm.bmHeight;++i)
	{
		//pDC->BitBlt(x,y,width,height,pSrcDC,xSrc,ySrc,dwRop);
		//(x,y)			: 屏幕左上角的坐标
		//(width,height): 要绘制的宽度和高度
		//pSrcDC		: 源图像(的DC)
		//(xSrc,ySrc)   : 图像上的左上角
		//dwRop			: 操作方式
		pDC->BitBlt(offset_x,offset_y+i,bm.bmWidth,1,&memDC,0,i,SRCCOPY);//一行一行显示
		Sleep(10);
	}




说明:上面程序实现了自上而下的逐行显示,自下而上、自左向右等特效实现方法类似。

2.2  向右移动进入特效
     方法:从右向左显示图像,每次显示的图像宽度增加
	//向右移动进入特效
	offset_x = 10;
	offset_y = bm.bmHeight+20;
	for(int w=1;w<=bm.bmWidth;++w)	//w是显示的宽度
	{
		
		pDC->BitBlt(offset_x,offset_y,w,bm.bmHeight,&memDC,bm.bmWidth-w,0,SRCCOPY);
		Sleep(10);
	}
                   

2.3 马赛克特效

    方法:将图像划分成小块,然后按照随机的顺序显示出每一小块
//将0到count-1 随机顺序形成一个数组
void rand_seq(int count,int seq_array[])
{
	for(int i=0;i<count;++i)
	{
		seq_array[i] = i;
	}

	//打乱 做1000次随机交换
	int swap_count=0;
	while(swap_count<1000)
	{	
		//生成一个随机数
		LARGE_INTEGER seed;
		QueryPerformanceCounter(&seed);
		srand((int)seed.QuadPart);
		int seq = rand()%count-1; //0到count-1

		//交换seq_array[seq] 和 seq_array[count-seq-1]
		int tmp = seq_array[seq];
		seq_array[seq] = seq_array[count-seq-1];
		seq_array[count-seq-1] = tmp;

		swap_count ++;
	}
}

	//马赛克效果:分成不同的块,随机显示
	offset_x = bm.bmWidth+20;
	offset_y = 10;
	int block_size = 10;				//10*10的小块,按行编号 0,1,2,3,4,5...block_count-1
	int bpr = bm.bmWidth/block_size;	//一行的方块数目,block_per_row
	int bpc = bm.bmHeight/block_size;
	int block_count = bpr*bpc;			//总共的方块数目

	int seq=-1;
	int* seq_array = new int[block_count]; 
	rand_seq(block_count,seq_array);	//获得随机顺序
	for(int i=0;i<block_count;++i)
	{
		seq = seq_array[i];			//要显示的块号
		int row = seq/bpr;			//所在行
		int col = seq%bpr;			//所在列
		pDC->BitBlt(offset_x+col*block_size,
					offset_y+row*block_size,
					block_size,
					block_size,
					&memDC,
					col*block_size,
					row*block_size,
					SRCCOPY);
		Sleep(1);
	}
	delete[] seq_array;


说明:由于写的随机顺序算法rand_seq不是很好,所以马赛克效果也不是很好。读者如果能否实现更好的随机排列算法,势必会得到更好的马赛克效果

2.4 雨滴特效

    方法:从图像的最后一行开始,每次显示一行,并将该行上面的每一行都与该行显示相同
	//雨滴特效
	offset_x = bm.bmWidth+20;
	offset_y = bm.bmHeight+20;
	for(int i=0;i<bm.bmHeight;++i)//外循环控制每次显示的图像行,循环一次,表示显示了一行
	{
		for(int j=0;j<bm.bmHeight-i;++j)//内循环控制绘制出雨滴轨迹
		{
			pDC->BitBlt(offset_x,offset_y+j,bm.bmWidth,1,&memDC,0,bm.bmHeight-i,SRCCOPY);
			
		}
		Sleep(10);
	}



注:本文为学习《数字图像处理原理与实践》(左飞等)过程中的笔记


转载本文请注明作者和出处

作者 :JarvisChu

出处:http://blog.csdn.net/jarvischu






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值