Search code examples
imagewxpythontile

In wxPython is it possible to create one image from a set of images?


I'm learning graphical programming via wxPython. I have created a set of tile images with the intention to stitch them all together in a way determined by various functions (already done) to create randomly generated maps for future use (effectively creating a tile-engine).

My current method of painting the map to the frame involves iterating through all 50x50 locations and drawing the 16x16bit png to each location inside the EVT_PAINT handler. This takes a few seconds and is inappropriate for what I intend (which is to have the frame act as a camera which can then pan across a much larger-than-displayed map).

My question is, is it possible to create a 'stitched' together image in the background, and simply draw that image with one line instead of drawing over and over again (which is what I suspect is taking up so much time)? Any other method (that works) is fine as well, I must admit I am not very experienced with programming in general and specifically not very experienced with graphical programming. Ideally I want to be able to draw only visible sections of this image, which is wrappable, so being able slice and re-stitch the 'meta-image' as appropriate would be great.

The EVT_PAINT code looks like this at the moment:

 def onpaint(self, event = None):
    dc = wx.PaintDC(self)
    dc.Clear()

    pposX = 0 #ppos = Pixel Position
    pposY = 0
    tposX = 0 #tpos = tile position, essentially the tile co-ordinates independent of pixel position
    tposY = 0
    while tposY < self.tTotalY: #loops through all y coordinates
        tposX = 0   
        while tposX < self.tTotalX: #loops through all x coordinates
            pposX = tposX*self.tsCurrent
            pposY = tposY*self.tsCurrent
            tiletype = self.getTileType(tposX,tposY,self.tTotalX,self.tTotalY)
            img = wx.Image((self.filepath + '\\' +str(tiletype)), wx.BITMAP_TYPE_ANY).ConvertToBitmap()              
            dc.DrawBitmap(img,pposX,pposY)
            img.Destroy()
            tposX += 1
        tposY += 1

Solution

  • You could save a lot of time by not reloading the image from the file and converting to a bitmap every time you paint. If you just load them once and then reuse them for each paint you may find that it will be fast enough.

    Additional optimization approaches to take depends on the nature of what you are drawing, and how much it may change over time. If it can be divided into a fairly static background, with minor things changing in the foreground then a good thing to do is to precreate a bitmap for the background and then in your paint handler you just draw the background bitmap and then draw the current state of the foreground on top of that. To make the big background you can create an empty bitmap of the right size, create a wx.MemoryDC that will target that bitmap, and then draw your tiles to that DC. When that is done the background bitmap can be saved for use in your paint handler.