My GUI toolkit, wxPython provides some methods for implementing a user zoom factor, however the quality isn't too good. I'm looking for ideas on how to create a zooming feature, which I know is complicated.
I have a bitmap representing my canvas which is drawn to. This is displayed inside a scrolled window.
Problems I forsee:
- performance when zoomed in and panning around the canvas
- difficulties with "real" coordinates and zoomed in coordinates
- image quality not degrading with the zoom
Using wxPython's SetUserScale() on its device contexts presents image quality like this - this is with a 1px line, at 30% zoomed in.
I'm just wondering the general steps I'll need to take and the challenges I'll encounter. Thanks for any suggestions
You can render your scene using OpenGL. You get hardware scaling and panning, which will probably be very fast. There are various smoothing filters available in OpenGL, too, and you can use GLSL if you want a custom filter.
If you want to do things manually, look into bilinear interpolation and bicubic interpolation.
Have you tried using GraphicsContext
?
Here's some sample code. It should be easy to drop into your existing code using the GCDC
wrapper. You may only need the line: dc = wx.GCDC(dc)
Rendering will be a lot slower! You could make this an option that could be enabled/disabled by the user.
alt text http://www.michaelfogleman.com/static/images/gcdc.png
import wx
import random
class Panel(wx.Panel):
def __init__(self, parent):
super(Panel, self).__init__(parent, -1)
self.Bind(wx.EVT_PAINT, self.on_paint)
self.lines = [[random.randint(0, 500) for i in range(4)] for j in range(100)]
def on_paint(self, event):
dc = wx.PaintDC(self)
dc = wx.GCDC(dc)
dc.SetUserScale(0.3, 0.3)
for line in self.lines:
dc.DrawLine(*line)
class Frame(wx.Frame):
def __init__(self):
super(Frame, self).__init__(None, -1, 'Test')
Panel(self)
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = Frame()
frame.Show()
app.MainLoop()