通过获取帧的维度与每一个帧的时间间隔来绘制gif图片 gif也是手机上用到最多的表情包动态图片
双缓冲 2D游戏经常用到的技术在内存中开辟一个空间来绘制图片 #include<windows.h>
#include<Gdiplus.h>
#pragma comment(lib,"Gdiplus.lib")
using namespace Gdiplus;
GdiplusStartupInput gdiplusstartupinput;
ULONG_PTR gdiplusTokeny;
#define WINDOW_WIDTH GetSystemMetrics(SM_CXSCREEN)
#define WINDOW_HEIGHT GetSystemMetrics(SM_CYSCREEN)
HDC hdc, hMemdc;
POINT point;
DWORD DrawGIF(HWND hwnd)//播放GIF动态图
{
GdiplusStartup(&gdiplusTokeny, &gdiplusstartupinput, NULL);
RECT rect;
GetClientRect(hwnd, &rect);
Image *pimage=new Image(L"c://4.gif");
int count = pimage->GetFrameDimensionsCount();
GUID *pDimensionIDs = new GUID[count];
pimage->GetFrameDimensionsList(pDimensionIDs, count);
int frameCount = pimage->GetFrameCount(&pDimensionIDs[0]);
delete []pDimensionIDs;
int Size = pimage->GetPropertyItemSize(PropertyTagFrameDelay);
PropertyItem* pItem = (PropertyItem*)malloc(Size);
pimage->GetPropertyItem(PropertyTagFrameDelay,Size,pItem);
GUID Guid = FrameDimensionTime;
int fcount = 0;
free(pItem);
while (TRUE)
{
hdc = GetDC(hwnd);
hMemdc = CreateCompatibleDC(hdc);
HBITMAP hbmp = CreateCompatibleBitmap(hdc,rect.right - rect.left, rect.bottom - rect.top);
SelectObject(hMemdc, hbmp);
Graphics graphics(hMemdc);
graphics.DrawImage(pimage, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
pimage->SelectActiveFrame(&Guid,fcount++);
if (fcount == frameCount)
fcount = 0;
BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
hMemdc, 0, 0, SRCCOPY);
ReleaseDC(hwnd,hdc);
DeleteDC(hMemdc);
DeleteObject(hbmp);
Sleep(100);
}
}
DWORD DrawImage(HWND hwnd)//双缓冲技术
{
hdc = GetDC(hwnd);
RECT rect;
GetClientRect(hwnd, &rect);
GetCursorPos(&point);
GdiplusStartup(&gdiplusTokeny, &gdiplusstartupinput, NULL);
Bitmap *p = new Bitmap(rect.right-rect.left,rect.bottom-rect.top);
Graphics graphics(p);
Image image(L"c://MP3//JPG/1.jpg");
Image imm(L"c://MP3//JPG/2.jpg");
graphics.DrawImage(&image, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
ScreenToClient(hwnd,&point);
graphics.DrawImage(&imm, point.x, point.y, 300, 300);
Graphics gr(hdc);
gr.DrawImage(p, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
delete p;
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_PAINT:
ValidateRect(hwnd,NULL);
SetTimer(hwnd, 90, NULL,NULL);
break;
case WM_TIMER:
SetCursor(FALSE);
//DrawImage(hwnd);
break;
case WM_DESTROY:
GdiplusShutdown(gdiplusTokeny);
PostQuitMessage(0);
break;
default:
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int _stdcall WinMain(HINSTANCE hinstance,//_stdcall 堆栈从右向左传递
HINSTANCE hPrevInstance,//实力程序
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcx;
wcx.cbClsExtra = 0;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.cbWndExtra = 0;
wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wcx.hInstance = hinstance;
wcx.lpfnWndProc = WndProc;
wcx.lpszClassName = L"a";
wcx.lpszMenuName = NULL;
wcx.style = CS_HREDRAW | CS_VREDRAW;
BOOL bRet;
bRet = RegisterClassEx(&wcx);
if (!bRet)
{
MessageBox(NULL, L"", L"", MB_OK);
return E_FAIL;
}
HWND hwnd = CreateWindowEx(WS_EX_CONTROLPARENT, L"a", NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hinstance, NULL);
if (!hwnd)
{
MessageBox(NULL, L"", L"", MB_OK);
return E_FAIL;
}
DrawGIF(hwnd);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg = { 0 };
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
}
}
}
|