【问题标题】:Caching a bitmap缓存位图
【发布时间】:2009-10-18 05:41:57
【问题描述】:

我正在使用 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);

没有渲染任何东西。

关于如何缓存位图的任何想法?

【问题讨论】:

    标签: c++ winapi gdi+


    【解决方案1】:

    Clone() 应该可以工作,但是如果没有看到您的代码(使用它),就很难知道发生了什么。作为替代方案,另一种(更迂回的)方法是在原始Bitmap 上调用GetHBITMAP(),存储GDI 位图句柄,然后在将来的重绘中使用Bitmap(HBITMAP, HPALETTE) 构造函数构造新的Bitmap

    【讨论】:

      【解决方案2】:

      与其将 img 声明为本地对象,不如将其设为静态对象或类的成员。然后在下一个 WM_PAINT 时就可以使用,无需复制。

      【讨论】:

      • 我不能。因为,要构造 img 我需要知道高度和宽度,这是根据我在 Draw 方法中所做的计算计算得出的。而且我无法创建一个简单的:Bitmap img;稍后将其分配给: img = Bitmap(...) 因为它没有无参数构造函数。如果这能解决,我的问题就解决了。
      • 那为什么不保存一个指向位图的指针呢?这样您就不需要预先分配它。
      猜你喜欢
      • 2015-12-07
      • 1970-01-01
      • 2014-02-24
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      相关资源
      最近更新 更多