gpt4 book ai didi

c++ - 离屏绘图GDI+

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:09:49 26 4
gpt4 key购买 nike

我有一个问题 - 我需要绘制两个 png 文件,一个放在另一个上。当我以通常的方式进行操作时,会出现“闪烁”效果(第一张图像在短时间内 overdraw 第二张图像)。我使用 GDI+ 库,我的 WM_PAINT 处理看起来像这样:

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, & ps );
displayImage(firstImage, hwnd);
displayImage(secondImage, hwnd);
EndPaint( hwnd, & ps );
break;
}

显示图像函数:

void displayImage(HBITMAP mBmp, HWND mHwnd)
{
RECT myRect;
BITMAP bm;
HDC screenDC, memDC;
HBITMAP oldBmp;
BLENDFUNCTION bf;

GetObject(mBmp, sizeof(bm), &bm);

bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0xff;

bf.AlphaFormat = AC_SRC_ALPHA;

screenDC = GetDC(mHwnd);
GetClientRect(mHwnd, &myRect);

if (mBmp == NULL)
FillRect(screenDC, &myRect, WHITE_BRUSH);

else
{
memDC = CreateCompatibleDC(screenDC);
oldBmp = (HBITMAP)SelectObject(memDC, mBmp);
AlphaBlend (screenDC, 0, 0, myRect.right,myRect.bottom, memDC, 0, 0, bm.bmWidth,bm.bmHeight, bf);
SelectObject(memDC, oldBmp);
DeleteDC(memDC);
ReleaseDC(mHwnd, screenDC);
}
}

加载文件到变量:

HBITMAP mLoadImg(WCHAR *szFilename)
{
HBITMAP result=NULL;

Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(szFilename,false);
bitmap->GetHBITMAP(NULL, &result);
delete bitmap;
return result;
}


firstImage = mLoadImg(L"data\\img\\screen.png");
secondImage = mLoadImg(L"data\\img\\screen2.png");

我听说我应该做一个离屏绘图。那应该是什么样子?

最佳答案

您不需要所有这些。您可以直接使用 GDI+:

static Gdiplus::Image *firstImage;
static Gdiplus::Image *secondImage;

case WM_CREATE: // or WM_INITDIALOG if it's dialog
{
firstImage = new Gdiplus::Image(L"data\\img\\screen.png");
secondImage = new Gdiplus::Image(L"data\\img\\screen2.png");
return 0;
}

case WM_PAINT:
{
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hwnd, &ps);

Gdiplus::Graphics gr(hdc);
gr.DrawImage(firstImage, 0, 0);
gr.DrawImage(secondImage, 0, 0);//<== this will draw transparently

EndPaint(hwnd, &ps);

return 0;
}

但是,这段代码仍然会背靠背绘制 2 张图像,可能会出现闪烁(就像您的原始代码一样)。在 WM_PAINT 中使用双缓冲,以便只完成一个 BltBlt。只需更改为:

if (msg == WM_PAINT)
{
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hwnd, &ps);

RECT rc;
GetClientRect(hwnd, &rc);
HDC memdc = CreateCompatibleDC(hdc);
HBITMAP hbitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
HGDIOBJ oldbmp = SelectObject(memdc, hbitmap);

FillRect(memdc, &rc, WHITE_BRUSH);
Gdiplus::Graphics gr(memdc);
gr.DrawImage(firstImage, 0, 0);
gr.DrawImage(secondImage, 0, 0);

BitBlt(hdc, 0, 0, rc.right, rc.bottom, memdc, 0, 0, SRCCOPY);

SelectObject(memdc, oldbmp);
DeleteObject(hbitmap);
DeleteDC(memdc);

EndPaint(hwnd, &ps);

return 0;
}

至于原代码:

void displayImage(HBITMAP mBmp, HWND mHwnd)
{
HDC hdc = GetDC(mHwnd);
...
}

您应该将函数声明更改为 void displayImage(HBITMAP mBmp, HWND mHwnd, HDC hdc) 然后您可以直接从 WM_PAINT hdc

关于c++ - 离屏绘图GDI+,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40349373/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com