开发者

wxpython - resize image without flicker?

I'm new to wxPython and GUI in general. Right now the application just displays a toolbar, statusbar, and the following panel. The panel contains a boxSizer with a staticBitmap in it. I'm trying to have an image resize itself to fit its container whenever the window is resized, but I'm running into a lot of flickering.

Summary

resizeImage() is called when the window is resized (EVT_SIZE fires)

resizeImage() resizes the panel to fit the new dimensions and then scales the image with scaleImage() and it is placed into the staticBitmap

resizeImage() basically grabs the image object, resizes it, sets it to a bitmap, and then sets it to the staticbitmap to be displayed.

Code

class Canvas(wx.Panel):
"""Panel used to display selected images"""

#---------------------------------------------------------------------------
def __init__(self, parent):
    """Constructor"""
    wx.Panel.__init__(self, parent)

    # Globals
    self.image        = wx.EmptyImage(1,1)
    self.control    = wx.StaticBitmap(self, wx.ID_ANY, 
                                     wx.BitmapFromImage(self.image))    
    self.background    = wx.BLACK
    self.padding    = 5
    self.imageList    = []
    self.current    = 0
    self.total        = 0

    # Register Events
    Publisher().subscribe(self.onLoadDirectory, ("load directory"))
    Publisher().subscribe(self.resizeImage, ("resize window"))

    # Set Layout
    self.mainSizer = wx.BoxSizer(wx.VERTICAL)
    self.mainSizer.Add(self.control, 1, wx.ALL|wx.CENTER|wx.EXPAND,
            self.padding)
    self.SetSizer(self.mainSizer)
    self.SetBackgroundColour(self.background)

#---------------------------------------------------------------------------
def scaleImage(self, image, maxWidth, maxHeight):
    """asd"""
    width    = image.GetWidth()
    height    = image.GetHeight()
    ratio    = min( maxWidth / width, maxHeight/ height );
    image    = image.Scale(ratio*width, ratio*height, wx.IMAGE_QUALITY_HIGH)
    result    = wx.BitmapFromImage(image)

    return result

#---------------------------------------------------------------------------
def loadImage(self, image):
    """Load image"""
    self.image = wx.Image(image, wx.BITMAP_TYPE_ANY)
    bmp = wx.BitmapFromImage(self.image)
    w, h = self.mainSizer.GetSize()
    w = w - self.padding*2
    h = h - self.padding*2
    bmp = self.scaleImage(self.image, w, h)        
    self.control.SetBitmap(bmp)

#---------------------------------------------------------------------------
def getImageIndex(self, path):
    """Retrieve index of image from imagePaths"""
    i = 0
    for image in self.imagePaths:
        if image == path:
            return i
        i += 1
    return -1

#---------------------------------------------------------------------------
def resizeImage(self, event):
    self.SetSize(event.data)
    if self.total:
        w = event.data[0] - self.padding*2
        h = event.data[1] - self.开发者_运维问答padding*2
        bmp = self.scaleImage(self.image, w, h)
        self.control.SetBitmap(bmp)

#---------------------------------------------------------------------------
def onLoadDirectory(self, event):
    """Load the image and compile a list of image files from directory"""
    self.folderPath        = os.path.dirname(event.data)
    self.imagePaths        = glob.glob(self.folderPath + "\\*.jpg")
    self.total            = len(self.imagePaths)
    self.current        = self.getImageIndex(event.data)
    self.SetSize(self.GetSize())
    self.loadImage(self.imagePaths[self.current])


Try drawing on a double buffered DC instead of using a StaticBitmap.


In your resizeImage method, it might help to add a Freeze and a Thaw, like this:

def resizeImage(self, event):
    self.SetSize(event.data)
    if self.total:
        w = event.data[0] - self.padding*2
        h = event.data[1] - self.padding*2
        self.Freeze()
        bmp = self.scaleImage(self.image, w, h)
        self.control.SetBitmap(bmp)
        self.Thaw()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜