tags:

views:

96

answers:

2
+1  Q: 

Caching a bitmap

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?

+1  A: 

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 call GetHBITMAP() on the original Bitmap, store the GDI bitmap handle and then construct the new Bitmap with the Bitmap(HBITMAP, HPALETTE) constructor in future repaints.

GRB
+1  A: 

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.

Mark Ransom
I can't. Because, to construct img I need to know the height and the width, which is calculated basing on the calculations that I do in the Draw method.And I can't create a simple: Bitmap img; and later on assign it to: img = Bitmap(...) because it has no parameterless constructor.If this would work out, my problem would be solved.
Karim
Then why not save a pointer to the Bitmap? That way you don't need to pre-allocate it.
Larry Osterman