Search code examples
c++imagewxwidgets

Sample code for c++ WxWidgets blit an image to the canvas


I am trying to make a basic GUI using wxWidgets and wxFormBuilber to display a chess gameboard and chess pieces from a sprite sheet. I would really appreciate some sample code for:

  1. uploading an image from a file
  2. blitting an image at a specific location

Solution

  • Here's a simplest example I can think of. This uses this set of pieces from wikipedia (licensed under the Creative Commons license). This example only draws the black pieces, but you should be able to figure out how to draw the white pieces with a few simple modifications.

    enter image description here

    // For compilers that support precompilation, includes "wx/wx.h".
    #include "wx/wxprec.h"
    
    #ifdef __BORLANDC__
        #pragma hdrstop
    #endif
    
    // for all others, include the necessary headers (this file is usually all you
    // need because it includes almost all "standard" wxWidgets headers)
    #ifndef WX_PRECOMP
        #include "wx/wx.h"
    #endif
    
    class MyFrame: public wxFrame
    {
        public:
            MyFrame();
    
        private:
            void OnPaint(wxPaintEvent& event);
    
            wxPanel* m_board;
            wxBitmap m_blackRook;
            wxBitmap m_blackKnight;
            wxBitmap m_blackBishop;
            wxBitmap m_blackQueen;
            wxBitmap m_blackKing;
            wxBitmap m_blackPawn;
    };
    
    MyFrame::MyFrame()
            :wxFrame(NULL, wxID_ANY, "Chess", wxDefaultPosition, wxSize(1000, 1000))
    {
        m_board = new wxPanel(this, wxID_ANY);
        m_board->Bind(wxEVT_PAINT, &MyFrame::OnPaint, this);
    
        // Load the image.
        wxImage im("c:\\640px-Chess_Pieces_Sprite.svg.png", wxBITMAP_TYPE_PNG);
    
        // Extract the images of the pieces from the larger image.
        wxBitmap b(im);
        m_blackKing = b.GetSubBitmap(wxRect(5,113,100,100));
        m_blackQueen = b.GetSubBitmap(wxRect(110,113,100,100));
        m_blackBishop = b.GetSubBitmap(wxRect(215,113,100,100));
        m_blackKnight = b.GetSubBitmap(wxRect(323,113,100,100));
        m_blackRook = b.GetSubBitmap(wxRect(433,113,100,100));
        m_blackPawn = b.GetSubBitmap(wxRect(535,113,100,100));
    }
    
    void MyFrame::OnPaint(wxPaintEvent&)
    {
        wxPaintDC dc(m_board);
        dc.Clear();
    
        // Draw thie light squares
        dc.SetPen(wxColour(209,139,71));
        dc.SetBrush(wxColour(209,139,71));
        dc.DrawRectangle(0,0,800,800);
    
        // Draw thie dark squares
        dc.SetPen(wxColour(255,206,158));
        dc.SetBrush(wxColour(255,206,158));
        for ( int i = 0 ; i< 8 ; ++i )
        {
            for ( int j = i%2 ; j< 8 ; j+=2 )
            {
                dc.DrawRectangle(i*100,j*100,100,100);
            }
        }
    
        // Draw thie black pieces
        dc.DrawBitmap(m_blackRook, 0, 0, true);
        dc.DrawBitmap(m_blackKnight, 100, 0, true);
        dc.DrawBitmap(m_blackBishop, 200, 0, true);
        dc.DrawBitmap(m_blackQueen, 300, 0, true);
        dc.DrawBitmap(m_blackKing, 400, 0, true);
        dc.DrawBitmap(m_blackBishop, 500, 0, true);
        dc.DrawBitmap(m_blackKnight, 600, 0, true);
        dc.DrawBitmap(m_blackRook, 700, 0, true);
    
        for ( int i = 0 ; i < 8 ; ++i )
        {
            dc.DrawBitmap(m_blackPawn, 100*i, 100, true);
        }
    }
    
    class MyApp : public wxApp
    {
        public:
            virtual bool OnInit()
            {
                ::wxInitAllImageHandlers();
                MyFrame* frame = new MyFrame();
                frame->Show();
                return true;
            }
    };
    
    wxIMPLEMENT_APP(MyApp);
    

    On windows, the application will look something like this:

    enter image description here

    The important items demonstrated here are

    1. loading the image.
    2. extracting subbitmaps for the individual pieces.
    3. drawing the pieces in a paint handler for the board.

    Obviously, you should change the location of the png file in line 38. If you want to take a few extra steps, you can embed the png file in your application.

    I tried to keep the example as simple as possible, so there are many things that could be improved upon. For example. I used a separate bitmap for each type of piece. If you want you can use a wxImageList instead. In addition it would be better to use an wxAutoBufferedPaintDC in the paint handler.