What is the most performant way to implement zoom to a cairo-drawn canvas?
Asked Answered
S

2

6

I have a wx.ScrolledWindow where is drawn on using cairo. I have implemented a zoom-functionality which right now redraws the whole content. But as there will be up to 200 curves to draw I should consider a more performant solution.

I have thought of these:

  • Buffering images for the zoom factors -1/+1 (Memory consuming)
  • Using librsvg and buffer an SVG image (I have read something about this. Does librsvg work under Windows too?)
  • Storing the cairo.Context after drawing groups of curves, and on zoom restoring it (just an idea.. is that possible?)

Are there other possibilities, and: what is the best solution?

Thanks a lot

Shanks answered 18/5, 2011 at 18:15 Comment(0)
P
1

Not really a concrete answer to your question, but I was faced with the same problem and just switched to matplotlib where a zoom and pan function is already implemented. I am not sure though if it is super performant. I have the feeling my program was running more smoothly before. I also tried out floatcanvas and floatcanvas2 but was not really happy with both of them.

Patellate answered 19/5, 2011 at 10:52 Comment(4)
Thanks for your answer. I looked into it, but I prefer sticking with cairo because of the already implemented export functions. I have gained performance though using a double buffer created with BitmapFromImageSurfaceShanks
Good to hear that you found a solution. I just wanted to mention that matplotlib also has an export function for svg, png and other formats. I am wondering how much faster cairo is though because I also have around 500 curves to draw.Patellate
just found out: matplotlib actually uses cairoPatellate
I think cairo itself can be really fast. The problem is likely to have different reasons. Maybe moving the whole drawing primitives to a C file improves the performance.Shanks
I
1

If you're double-buffering anyway, why not do a quick bitmap scale as a "preview" while waiting for the newly redrawn vector image? I confess I don't know how to do this. But if you can make it work, it should work! :)

Ichinomiya answered 23/6, 2011 at 6:32 Comment(2)
Thanks for the idea. I tried it by converting the wx.Bitmap buffer to a wx.Image, using Image.Scale() and converting it back with BitmapFromImage. But this is almost as slow as the cairo drawing itself, so there is no effect. If there is a faster method, i'd appreciate knowing about it :)Shanks
I'm not sure what's involved in converting to wx.Image, but you can probably avoid that (perhaps not easily, though) by doing it manually. For a 100% zoom, you're just doubling the "size" of each pixel in each direction. So you can loop through a quarter of the image, read one pixel, write it 4 times in a square (x,y)(x+1,y)(x,y+1)(x+1,y+1). Even for a full screen bitmap, this kind of minor processing should be quite fast. For other zoom factors, you might need a little light interpolation.Ichinomiya

© 2022 - 2024 — McMap. All rights reserved.