views:

347

answers:

2

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

+2  A: 

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.

strager
A: 

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

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()
FogleBird
yeah, the decreased performance is why I'm trying to find alternative solutions. Unfortunately my lack of math skills to formulate how to do zoom in stuff leaves me with little other choices
Steven Sproat