缓存位图
我正在使用 C++ 编写 Win32 应用程序。
在这个应用程序中,我正在处理 WM_PAINT 消息:
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GdiplusStartup(&gdiplusToken, &gdiPlusStartup, 0);
DrawM(ps.hdc, hWnd);
EndPaint(hWnd, &ps);
break;
在 DrawM 函数中,我有类似这样的内容:
void DrawMap(HDC hdc, HWND hWnd)
{
if(!isDrawn)
{
// (some calculations)
Graphics g(hdc);
Bitmap img(max_x, max_y, &g);
int zoom_factor = 50;
for(int i = 0; i< segments.size(); i++)
{
// (some math)
for(int j = 0; j < segments.at(i).point_count; j++)
// (another dose of math)
g.DrawLines(&pen, segmentPoints, segments.at(i).point_count);
delete [] segmentPoints;
}
g.Save();
isDrawn = true;
}
else
{
// here is the problem
}
}
在上面的代码中,我想做的是渲染图像一次,然后在窗口打开时渲染图像。调整大小、移动或发生任何需要重新绘制的事情都不会从头开始渲染位图,而是应该使用缓存的位图。
问题是 Bitmap 不允许复制(复制构造函数拒绝复制)。 另一个问题是,当我尝试将图像保存到文件或流中时,我收到“无效参数”错误(即返回代码为 2):
CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
img.Save(_T("m.png"), &Gdiplus::ImageFormatPNG, NULL);
->clone() 似乎也不起作用,因为当我定义一个指向位图的指针时,将位图克隆到它,并在我使用的“else”语句中:
Graphics g(hdc);
g.DrawImage(bmpClone, 50, 50);
没有渲染任何内容。
关于如何缓存位图有什么想法吗?
I'm writing a Win32 application using C++.
In this application I'm handling the WM_PAINT message:
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GdiplusStartup(&gdiplusToken, &gdiPlusStartup, 0);
DrawM(ps.hdc, hWnd);
EndPaint(hWnd, &ps);
break;
And in the DrawM function I'm having something like this:
void DrawMap(HDC hdc, HWND hWnd)
{
if(!isDrawn)
{
// (some calculations)
Graphics g(hdc);
Bitmap img(max_x, max_y, &g);
int zoom_factor = 50;
for(int i = 0; i< segments.size(); i++)
{
// (some math)
for(int j = 0; j < segments.at(i).point_count; j++)
// (another dose of math)
g.DrawLines(&pen, segmentPoints, segments.at(i).point_count);
delete [] segmentPoints;
}
g.Save();
isDrawn = true;
}
else
{
// here is the problem
}
}
In the code above, what I wanted to do, is to render the image once, and later on when the window is resized, moved or anything happens to it that requires repainting will not render the Bitmap from scratch, instead it should use a cached one.
The problem is that Bitmap does not allow copying (the copy constructor denies it).
Another problem is that, when I'm trying to save the image to a file or a stream I receive an "Invalid parameter" error (i.e the return code is 2):
CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
img.Save(_T("m.png"), &Gdiplus::ImageFormatPNG, NULL);
->clone() also seems that it is not working, because when I define a pointer to a Bitmap, clone the bitmap to it and in the "else" statement I use:
Graphics g(hdc);
g.DrawImage(bmpClone, 50, 50);
Nothing is rendered.
Any ideas on how to cache the Bitmap?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Clone()
应该可以工作,但是如果没有看到您的代码(使用它),就很难知道发生了什么。作为替代方案,另一种(更迂回的)方法是在原始位图上调用 GetHBITMAP(),存储 GDI 位图句柄,然后构造新的位图 与位图(HBITMAP, HPALETTE)
未来重绘的构造函数。Clone()
should work, but without seeing your code (which uses it) it's hard to know what's going on. As an alternative, another (more circuitous) approach would be to callGetHBITMAP()
on the originalBitmap
, store the GDI bitmap handle and then construct the newBitmap
with theBitmap(HBITMAP, HPALETTE)
constructor in future repaints.不要将 img 声明为本地对象,而是将其声明为静态对象或类的成员。然后它将在下一个 WM_PAINT 中可用,而无需复制。
Instead of declaring img as a local object, make it a static or a member of a class. Then it will be available at the next WM_PAINT without needing to be copied.