ImagePanel with autofit and zoom

Hi,

I think it is hard To Do using a combination of ScrolledPanel and StaticBitmap (they are “static”).

As mentioned in the docs of StaticBitmap, native implementations on some platforms are only meant for the display of the small icons in the dialog boxes. If you have rapidly changing big images, or want to do dynamic control like pan & zoom, it is better to write your own control with PaintDC or double-buffered DC (to reduce flicker).

Another option is to use wx.lib.floatcanvas. It implements double buffering and perfect pan & zoom interface. This is a small example.

import wx
from wx.lib.floatcanvas.FCObjects import ScaledBitmap
from wx.lib.floatcanvas.FloatCanvas import FloatCanvas

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        w, h = self.GetSize()
        self.image = wx.Image("sample.png")
        self.Canvas = FloatCanvas(self, size=(w,h))
        self.bitmap = self.Canvas.AddScaledBitmap(self.image, (0,0), h, 'cc')
        self.Canvas.Draw()
        self.Canvas.Bind(wx.EVT_MOUSEWHEEL, self.OnWheel)
        self.Canvas.Bind(wx.EVT_LEFT_DCLICK, self.ZoomToFit)
    
    def OnWheel(self, event):
        self.Canvas.Zoom(
            1/1.2 if event.GetWheelRotation() < 0 else 1.2,
            event.Position, "Pixel", keepPointInPlace=True)
    
    def ZoomToFit(self,event):
        self.Canvas.ZoomToBB()

if __name__ == "__main__":
    app = wx.App()
    frm = Frame(None)
    frm.Show()
    app.MainLoop()

Unfortunately, there are no scroll bars (there may be a way to make custom scroll bars). Alternatively, the original code in “wx/lib/floatcanvas/GUIMode.py” will help you to implement pan-move.

1 Like