Basj
Basj

Reputation: 46453

Rescale image when parent is resized in wxPython

I need to be able to rescale an image (in realtime) in a wx.Panel when parent wx.Frame is resized (for example for wxPython for image and buttons (resizable)).

This code now works, the behaviour is like in a standard Photo Viewer : the image fits perfectly the parent window, and the rescaling respects aspect ratio.

import wx

class MainPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, style=wx.FULL_REPAINT_ON_RESIZE)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.img = wx.Image('background.png', wx.BITMAP_TYPE_PNG)
        self.imgx, self.imgy = self.img.GetSize()

    def OnPaint(self, event):
        dc = wx.PaintDC(self)
        dc.Clear()
        x,y = self.GetSize()
        posx,posy = 0, 0
        newy = int(float(x)/self.imgx*self.imgy)
        if newy < y:
            posy = int((y - newy) / 2) 
            y = newy
        else:
            newx = int(float(y)/self.imgy*self.imgx)
            posx = int((x - newx) / 2)
            x = newx        

        img = self.img.Scale(x,y, wx.IMAGE_QUALITY_HIGH)
        self.bmp = wx.BitmapFromImage(img)
        dc.DrawBitmap(self.bmp,posx,posy)

class MainFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, title='Test', size=(600,400))
        self.panel = MainPanel(self)
        self.Show()

app = wx.App(0)
frame = MainFrame(None)
app.MainLoop()        

Before continuing to implement some things, I would to know :

Upvotes: 1

Views: 1027

Answers (1)

VZ.
VZ.

Reputation: 22688

This is not a bad way to do it but there are a couple of things you could easily optimize:

  1. Don't call wxImage::Scale() every time in OnPaint(). This is a slow operation and you should do it only once, in your wxEVT_SIZE handler instead of doing it every time you repaint the window.
  2. Call SetBackgroundStyle(wxBG_STYLE_PAINT) to indicate that your wxEVT_PAINT handler already erases the background entirely, this will reduce flicker on some platforms (you won't see any difference on the others which always use double buffering anyhow, but it will still make repainting marginally faster even there).

As for the mouse clicks, I think you don't have any choice but to translate the coordinates yourself.

Upvotes: 1

Related Questions