PNG透明加载实现动画

png透明加载实现动画


第一次做png透明加载实现动画时,遇到几个问题,贴出来,以备下次查找。
定时器中代码如下:
void CttDlg::OnTimer(UINT_PTR nIDEvent)
{

//----------------------利用picture控件----------------------
	static int imageCounter = 0;
	CRect kjrect;
	GetDlgItem(IDC_STATIC)->GetWindowRect(kjrect);
	ScreenToClient(kjrect);
	HWND hwnd = GetSafeHwnd(); //获取窗口的HWND
	::InvalidateRect( hwnd, kjrect, true ); //或者 ::InvalidateRect( hwnd, NULL, false );
	::UpdateWindow(hwnd);


	CString path;
	path.Format(_T("image/4e079535e5dde7115e3b672da7efce1b9f1661e100%02d.png"), imageCounter);
	CImage image;
	image.Load(path);
	if (image.GetBPP() == 32) //确认该图像包含Alpha通道
	{
		for (int i=0; i
    
    
     
     GetClientRect(&rect);

	image.Draw(GetDlgItem(IDC_STATIC)->GetDC()->m_hDC,rect.left, rect.top, 100, 100, 0, 0, 100, 100 );
 
	imageCounter++;
	imageCounter = imageCounter % 30;
	CDialogEx::OnTimer(nIDEvent);

//----------------------直接贴图----------------------
// 	static int imageCounter = 0;
// 	CRect kjrect(30, 60, 130, 160);
// 	HWND hwnd = GetSafeHwnd(); //获取窗口的HWND
// 	::InvalidateRect( hwnd, kjrect, true ); //或者 ::InvalidateRect( hwnd, NULL, false );
// 	::UpdateWindow(hwnd);
// 
// 	CString path;
// 	path.Format(_T("image/4e079535e5dde7115e3b672da7efce1b9f1661e100%02d.png"), imageCounter);
// 	CImage image;
// 	image.Load(path);
// 	if (image.GetBPP() == 32) //确认该图像包含Alpha通道
// 	{
// 		for (int i=0; i
     
     
      
      m_hDC*/GetDC()->GetSafeHdc(), 30, 60, 100, 100, 0, 0, 100, 100 );
// 	imageCounter++;
// 	imageCounter = imageCounter % 30;
// 	CDialogEx::OnTimer(nIDEvent);
}

     
     
    
    

整个逻辑比较简单,设定定时器,在定时器里面实现加载png图片,主要说明下遇到的几个问题。
首先,就是png的透明加载,经过查阅资料后,还是在加载png图片后,对数据进行了转换:
if (image.GetBPP() == 32) //确认该图像包含Alpha通道
	{
		for (int i=0; i<image.GetWidth(); i++)
		{
			for (int j=0; j<image.GetHeight(); j++)
			{
				byte *pByte = (byte *)image.GetPixelAddress(i, j);
				pByte[0] = pByte[0] * pByte[3] / 255;
				pByte[1] = pByte[1] * pByte[3] / 255;
				pByte[2] = pByte[2] * pByte[3] / 255;
			}
		}
	}
其次,图片已经透明加载了,不过动画效果存在问题,前面加载的图片没有消失,没那就刷新:
	HWND hwnd = GetSafeHwnd(); //获取窗口的HWND
	::InvalidateRect( hwnd, NULL, true ); //或者 ::InvalidateRect( hwnd, NULL, false );
	::UpdateWindow(hwnd);
问题出现了,如果将定时器时间设置比较小,那么明显看到窗口闪烁非常厉害,原来上面第二条代码中NULL是刷新的整个窗口,参见InvalidateRect用法,将第二个参数设置为需要刷新的位置就可以了:
 
	CRect kjrect;
	GetDlgItem(IDC_STATIC)->GetWindowRect(kjrect);
	ScreenToClient(kjrect);
	HWND hwnd = GetSafeHwnd(); //获取窗口的HWND
	::InvalidateRect( hwnd, kjrect, true ); //或者 ::InvalidateRect( hwnd, NULL, false );
	::UpdateWindow(hwnd);
注意控件的位置转换:
	GetDlgItem(IDC_STATIC)->GetWindowRect(kjrect);//获得子控件的屏幕坐标;
	ScreenToClient(kjrect);//子控件屏幕坐标映射到控件客户区;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值