Thursday, March 3, 2011

wxWidgets: Is there any way to avoid or to speed up wxBitmap::ConvertToImage() ?

To get some smooth graphics, I want to draw oversampled by factor 2 and scale down afterwards.

So what I am doing is to draw oversampled on a wxBitmap in a wxMemoryDC, and then scale it down before copying to my dc. The code below works fine, but bitmapOversampled.ConvertToImage(); is extremely slow.

Is there any way to achieve the same without having to convert from wxBitmap to wxImage and vice versa?


    void OnPaint
    ( wxPaintEvent& event )
    {
        wxBitmap bitmapOversampled(m_width * 2, m_height * 2);
        wxMemoryDC memDC(bitmapOversampled);

        // Draw the elements.
        drawElements(&memDC);

        // Scale to correct size.
        wxImage image = bitmapOversampled.ConvertToImage();
        image.Rescale(m_width, m_height);
        memDC.SelectObject(wxBitmap(image));

        // Copy to dc.
        wxPaintDC dc(this);
        dc.Blit(0, 0, m_width, m_height, &memDC, 0, 0);
    };
From stackoverflow
  • Sadly, there is no portable wx method to do that scaling faster. But there is a Scale method in the Gtk port in wxBitmap. You can use that for wxGTK. For wxMSW, you can use StretchBlt of the win32 API. There are methods in wxDC that will provide you with the native HDC handle for Windows.

    You can make it somewhat more straight forward if you draw directly:

    wxPaintDC dc(this);
    dc.DrawBitmap(image, 0, 0, false);
    

    Also, don't recreate the bitmap in each paint event. Store it as a member, and recreate it only when you get a wxSizeEvent. It will probably considerably speed up your program.

    Another way is to drop the scaling altogether and use wxGraphicsContext. It uses Cairo on wxGTK, and gdi+ on wxMSW. It's relatively new, but can draw antialiased.

0 comments:

Post a Comment