VC只用GDI实现位图展现简单特效
来源:互联网 发布:淘宝微淘首页 编辑:程序博客网 时间:2024/05/20 11:51
展示截图(略大,4.24M):
Demo下载(需要1积分):http://download.csdn.net/detail/joneeky/7860555
这些把位图加载到内存DC上的代码需要重复使用,于是定义成宏:
#define READY_CODE\CGditestDlg *pMainDlg = (CGditestDlg *)pParam;\CDC *pDC = pMainDlg->GetDC();\CBitmap bmp;\if (1 == pMainDlg->m_counter)\{\bmp.LoadBitmap(IDB_BITMAP1);\pMainDlg->m_counter = 2;\}\else if (2 == pMainDlg->m_counter)\{\bmp.LoadBitmap(IDB_BITMAP2);\pMainDlg->m_counter = 3;\}\else\{\bmp.LoadBitmap(IDB_BITMAP3);\pMainDlg->m_counter = 1;\}\CDC dcMem;\dcMem.CreateCompatibleDC(pDC);\dcMem.SelectObject(&bmp);\BITMAP bm;\bmp.GetBitmap(&bm);\pMainDlg->Invalidate();\EnumChildWindows(pMainDlg->GetSafeHwnd(),\EnumChildProc, 0L);#define CLEAN_CODE\dcMem.DeleteDC();\bmp.DeleteObject();\EnumChildWindows(\pMainDlg->GetSafeHwnd(),\EnumChildProc, 1L);\#define PI3.14//弧度 = 2π * 角度 / 360#define RADIAN(degree)((float)((2 * PI * degree) / 360))
/*从上飞入*/UINT CGditestDlg::FlyIntoFromTop(LPVOID pParam){READY_CODEfor (int ySrc = bm.bmHeight; ySrc >= 0; ySrc -= 10){pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, 0, ySrc, SRCCOPY);Sleep(1);}CLEAN_CODEreturn 0;}
/*从左飞入*/UINT CGditestDlg::FlyIntoFromLeft(LPVOID pParam){READY_CODEfor (int xSrc = bm.bmWidth; xSrc >= 0; xSrc -= 10){pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, xSrc, 0, SRCCOPY);Sleep(1);}CLEAN_CODEreturn 0;}
/*从上展开*/UINT CGditestDlg::UnfoldFromTop(LPVOID pParam){READY_CODEfor (int htDes = 0; htDes <= bm.bmHeight; htDes += 10){pDC->BitBlt(0, 0, bm.bmWidth, htDes, &dcMem, 0, 0, SRCCOPY);Sleep(1);}CLEAN_CODEreturn 0;}
/*从左展开*/UINT CGditestDlg::UnfoldFromLeft(LPVOID pParam){READY_CODEfor (int wtDes = 0; wtDes <= bm.bmWidth; wtDes += 10){pDC->BitBlt(0, 0, wtDes, bm.bmHeight, &dcMem, 0, 0, SRCCOPY);Sleep(1);}CLEAN_CODEreturn 0;}
/*水平百叶窗*/UINT CGditestDlg::HorizontalWindow(LPVOID pParam){READY_CODEint n = bm.bmHeight / 8;for (int htDes = 0; htDes <= n; htDes += 1){for (int i = 0; i < 8; i++){pDC->BitBlt(0, n * i, bm.bmWidth, htDes, &dcMem, 0, n * i, SRCCOPY);}Sleep(10);}CLEAN_CODEreturn 0;}
/*垂直百叶窗*/UINT CGditestDlg::VerticalWindow(LPVOID pParam){READY_CODEint n = bm.bmWidth / 8;for (int wtDes = 0; wtDes <= n; wtDes += 1){for (int i = 0; i < 8; i++){pDC->BitBlt(n * i, 0, wtDes, bm.bmHeight, &dcMem, n * i, 0, SRCCOPY);}Sleep(10);}CLEAN_CODEreturn 0;}
拉直其实和百叶窗相差不了多少,也是分块同步显示,但是每一块是慢慢变大的。
/*往下拉直*/UINT CGditestDlg::StraightenToBottom(LPVOID pParam){READY_CODEint n = bm.bmHeight / 8;for (int htDes = 0; htDes <= n; htDes += 1){for (int i = 0; i < 8; i++){pDC->BitBlt(0, htDes * i, bm.bmWidth, htDes, &dcMem, 0, n * i, SRCCOPY);}Sleep(10);}CLEAN_CODEreturn 0;}
/*往右拉直*/UINT CGditestDlg::StraightenToRight(LPVOID pParam){READY_CODEint n = bm.bmWidth / 8;for (int wtDes = 0; wtDes <= n; wtDes += 1){for (int i = 0; i < 8; i++){pDC->BitBlt(wtDes * i, 0, wtDes, bm.bmHeight, &dcMem, n * i, 0, SRCCOPY);}Sleep(10);}CLEAN_CODEreturn 0;}
/*由小变大*/UINT CGditestDlg::SmallToLarge(LPVOID pParam){READY_CODEfloat x, y, w, h;float base = 0;pDC->SetStretchBltMode(HALFTONE);while ((int)(base += 10) <= bm.bmWidth){w = base;h = base * ((float)bm.bmHeight / (float)bm.bmWidth);x = (float)bm.bmWidth / 2 - w / 2;y = (float)bm.bmHeight / 2 - h / 2;pDC->StretchBlt((int)x, (int)y, (int)w, (int)h, &dcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);Sleep(10);}CLEAN_CODEreturn 0;}
旋转变大比较复杂,在上网找到可以完成位图按任意弧度旋转的代码改了一下,使其可以指定显示的大小:
最后一个参数的颜色值,指定图像旋转后空出来的位置填充的颜色
HBITMAP GetRotatedBitmap(HBITMAP hBitmap, float radians, int width, int height, COLORREF clrBack) { // Create a memory DC compatible with the display CDC sourceDC, destDC; sourceDC.CreateCompatibleDC( NULL ); destDC.CreateCompatibleDC( NULL ); // Get logical coordinates BITMAP bm, bmOld; ::GetObject( hBitmap, sizeof( bm ), &bm ); bmOld = bm;bm.bmWidth = width;bm.bmHeight = height;float cosine = (float)cos(radians); float sine = (float)sin(radians); // Compute dimensions of the resulting bitmap // First get the coordinates of the 3 corners other than origin int x1 = (int)(bm.bmHeight * sine); int y1 = (int)(bm.bmHeight * cosine); int x2 = (int)(bm.bmWidth * cosine + bm.bmHeight * sine); int y2 = (int)(bm.bmHeight * cosine - bm.bmWidth * sine); int x3 = (int)(bm.bmWidth * cosine); int y3 = (int)(-bm.bmWidth * sine); int minx = min(0,min(x1, min(x2,x3))); int miny = min(0,min(y1, min(y2,y3))); int maxx = max(0,max(x1, max(x2,x3))); int maxy = max(0,max(y1, max(y2,y3))); int w = maxx - minx; int h = maxy - miny; // Create a bitmap to hold the result HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL), w, h); HBITMAP hbmOldSource = (HBITMAP)::SelectObject( sourceDC.m_hDC, hBitmap ); HBITMAP hbmOldDest = (HBITMAP)::SelectObject( destDC.m_hDC, hbmResult ); // Draw the background color before we change mapping mode HBRUSH hbrBack = CreateSolidBrush( clrBack ); HBRUSH hbrOld = (HBRUSH)::SelectObject( destDC.m_hDC, hbrBack ); destDC.PatBlt( 0, 0, w, h, PATCOPY ); ::DeleteObject( ::SelectObject( destDC.m_hDC, hbrOld ) ); // We will use world transform to rotate the bitmap SetGraphicsMode(destDC.m_hDC, GM_ADVANCED); XFORM xform; xform.eM11 = cosine; xform.eM12 = -sine; xform.eM21 = sine; xform.eM22 = cosine; xform.eDx = (float)-minx; xform.eDy = (float)-miny; SetWorldTransform( destDC.m_hDC, &xform ); // Now do the actual rotating - a pixel at a time //destDC.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &sourceDC, 0, 0, SRCCOPY ); destDC.SetStretchBltMode(HALFTONE);destDC.StretchBlt(0, 0, bm.bmWidth, bm.bmHeight, &sourceDC, 0, 0, bmOld.bmWidth, bmOld.bmHeight, SRCCOPY);// Restore DCs ::SelectObject( sourceDC.m_hDC, hbmOldSource ); ::SelectObject( destDC.m_hDC, hbmOldDest ); return hbmResult; }
还有就是我使用了双缓冲,怎么还闪烁得这么厉害我也不清楚了。
/*旋转变大*/UINT CGditestDlg::LargerWithSpin(LPVOID pParam){//READY_CODECGditestDlg *pMainDlg = (CGditestDlg *)pParam;CDC *pDC = pMainDlg->GetDC();pMainDlg->Invalidate();EnumChildWindows(pMainDlg->GetSafeHwnd(), EnumChildProc, 0L);pDC->SetStretchBltMode(HALFTONE);CBitmap bmp;if (1 == pMainDlg->m_counter){bmp.LoadBitmap(IDB_BITMAP1);pMainDlg->m_counter = 2;}else if (2 == pMainDlg->m_counter){bmp.LoadBitmap(IDB_BITMAP2);pMainDlg->m_counter = 3;}else{bmp.LoadBitmap(IDB_BITMAP3);pMainDlg->m_counter = 1;}HBITMAP hBmp;CDC dcMem;CBitmap *pbmpRotated;BITMAP bm;int degree = 0;float width, height;float base = 0;long oldWidth, oldHeight;float x, y;int lastX = 0, lastY = 0, lastWidth = 0, lastHeight = 0;dcMem.CreateCompatibleDC(pDC);bmp.GetBitmap(&bm);oldWidth = bm.bmWidth;oldHeight = bm.bmHeight;CRect rcWnd;pMainDlg->GetWindowRect(&rcWnd);CBitmap bmpBkgd;CDC dcBkgd;dcBkgd.CreateCompatibleDC(pDC);bmpBkgd.CreateCompatibleBitmap(pDC, rcWnd.Width() + 200, rcWnd.Height() + 200);dcBkgd.SelectObject(&bmpBkgd);dcBkgd.FillSolidRect(0, 0, rcWnd.Width() + 200, rcWnd.Height() + 200, RGB(255, 174 ,201));while (1){if (base <= oldWidth){base += 15;}if (base > oldWidth && degree == 0){break;}width = base;height = base * ((float)oldHeight / (float)oldWidth);hBmp = GetRotatedBitmap((HBITMAP)bmp.GetSafeHandle(), RADIAN(degree), (int)width, (int)height, RGB(255, 174 ,201));pbmpRotated = CBitmap::FromHandle(hBmp);dcMem.SelectObject(pbmpRotated);pbmpRotated->GetBitmap(&bm);x = (float)oldWidth / 2 - (float)bm.bmWidth / 2;y = (float)oldHeight / 2 - (float)bm.bmHeight / 2;pDC->BitBlt(lastX, lastY, lastWidth, lastHeight, &dcBkgd, 0, 0, SRCCOPY);pDC->BitBlt((int)x, (int)y, bm.bmWidth, bm.bmHeight, &dcMem, 0, 0, SRCCOPY);lastX = (int)x;lastY = (int)y;lastWidth = bm.bmWidth;lastHeight = bm.bmHeight;pbmpRotated->DeleteObject();degree = (degree += 15) > 360 ? 0 : degree;Sleep(1);}dcMem.DeleteDC();dcBkgd.DeleteDC();bmpBkgd.DeleteObject();EnumChildWindows(pMainDlg->GetSafeHwnd(), EnumChildProc, 1L);//CLEAN_CODEreturn 0;}
0 0
- VC只用GDI实现位图展现简单特效
- GDI实现图像的简单显示特效
- VC位图的特效
- VC中使用GDI函数实现位图的透明
- VC中使用GDI函数实现位图的透明
- VC中使用GDI函数实现位图的透明
- GDI位图实现
- vc gdi 位图的使用
- VC MFC GDI 位图旋转算法
- VC MFC GDI 位图旋转算法
- GDI+实现各种图像特效
- (转)VC下的位图特效
- 使用GDI+实现24 位图转32位位图
- VC 透明位图 实现透明位图类
- VC实现BMP位图实现
- VC/MFC实现:位图CBitmap对象保存成为bmp,bmp转jpg,截屏保存jpg(GDI+)
- 只用UILabel实现简单登陆页面
- 使用GDI实现视频字幕及特效
- UIImage的几点建议
- android申请权限列表
- linux下性能监控shell脚本实现系列一(服务器整体性能监控)
- 生产者-消费者问题变形
- 父子进程共享的资源
- VC只用GDI实现位图展现简单特效
- java 操作数据库clob类型大字段
- 生产者与消费者问题
- 开源ext2read代码走读之-ext2文件系统中的超级块及对应代码
- 致我们终将忘记的算法(数组也疯狂)
- android模拟硬键盘操作
- hadoop 2.5.0安装(虚拟机)
- STL list讲解
- 神奇的算法:B树