I do not know, but from what I can tell you from my knowledge of basic math
and images, at 8192 sq, for a 24bit bitmap, the memory needed is 200 meg,
unless it is intelligently clipping. Where as at 4096, the image only takes
up 50 meg.
Maybe your system can't malloc 200meg at a time? (either platform or, no
contiguous memory block exists that large)
Just guessing...
-J
-----Original Message-----
From: Bob Klimek [mailto:klimek@grc.nasa.gov]
Sent: Wednesday, January 08, 2003 3:59 PM
To: wxPython-users@lists.wxwindows.org
Subject: Re: [wxPython-users] zoom and scroll is slow
At 06:01 PM 1/7/2003 -0800, you wrote:
>Bob Klimek wrote:
>>Hi,
>>I've run into a speed problem when I zoom in on an image. I use PIL to
>>load an image and convert it to wxImage to display in wx. The problem is,
>>it gets very slow when the zoom factor gets to 3 zoom steps and above (I
>>double the image size with each zoom step). I'm using wxScrolledWindow to
>>manage the scroll bars and everything works well except for the speed.
>>To zoom in, a PIL function resizes the image, which is then converted to
>>wxImage in OnPaint(). After 3 zoom steps the image size is 4K x 4K and
>>things get very slow, especially during scrolling.
>>Couple of options I've considered is to not scale the PIL image but only
>>the wxImage or to redraw only a viewport area that is currently being
>>displayed, neither of which I know how to do.
>>What is the best way to zoom and scroll to make it more responsive?
>
>In addition to the other suggestions, let me add these:
>
>1. You should not be doing image scaling, conversion, etc in your
>EVT_PAINT. EVT_PAINT should only Blit the visible portion of the image
>and return.
>
>2. A further optimization is to only Blit those regions of the visible
>portion of the window that need updating, you can use the
>wxPaintDC.GetUpdateRegion() method to find out what they are. See
>demo/ColourDB.py for a simplistic example of using the update region. This
>will also help scrolling since only the parts of the image "uncovered" by
>the scroll need repainting.
>
>3. Do the scaling, PIL conversion, and etc. only once and save the results
>until you zoom again.
Thanks for the suggestions. So far I've come half way in getting a decent
zoom and scroll. I've taken Robb Shecter's suggestion of scaling and
converting wxImage to a bitmap when I do the zooming and then in OnPaint()
I just call "dc.DrawBitmap(self.bitmap, 0,0)". I'd imagine that DrawBitmap
calls Blit internally.
That makes for a quick and responsive scrolling (so if I understand your
suggestions correctly, 1 and 2 are taken care of, since they pertained to
scrolling only).
But the zooming is still slow since wxPython (or PIL) still has to scale
the image. After clicking the zoom button 3 times, the image size goes from
512x512 to 4096x4096. The last zoom step takes about 2 seconds. However,
clicking the zoom one more time hangs the program for about 20 seconds and
then prints the following traceback:
My system: (Python2.2.2, wxPython2.3.4.2, Win2000).
Did the image get too big? Is this a bug in wxPython? The code that
produced it is below.
Bob
1024 1024
2048 2048
4096 4096
8192 8192
Traceback (most recent call last):
File "SpotlightMain.py", line 255, in OnZoomIn
self.iPanel.Zoom(2.0)
File "SpotlightMain.py", line 91, in Zoom
self.display2()
File "SpotlightMain.py", line 98, in display2
dc.DrawBitmap(self.bitmap, 0,0)
File "D:\Python22\lib\site-packages\wxPython\gdi.py", line 784, in
DrawBitmap
val = apply(gdic.wxDC_DrawBitmap,(self,) + _args, _kwargs)
wxPython.wxc.wxPyAssertionError: C++ assertion "wxAssertFailure" failed in
e:\pr
ojects\wx\src\msw\dc.cpp(907): invalid bitmap in wxDC::DrawBitmap
NOTE: The parameter "scale" is 2.0 when zooming in.
def Zoom(self, scale):
h = self.image.GetHeight()
w = self.image.GetWidth()
newWidth = int(round(float(w) * scale))
newHeight = int(round(float(h) * scale))
print newWidth, newHeight
self.image.Rescale(newWidth, newHeight)
#self.manageScrollbars(newWidth, newHeight, scale)
self.SetScrollbars(10, 10, newWidth/10, newHeight/10)
self.display2()
def display2(self):
if self.image:
dc = wxClientDC(self)
self.PrepareDC(dc)
self.bitmap = self.image.ConvertToBitmap()
dc.DrawBitmap(self.bitmap, 0,0)
def OnPaint(self, event):
dc = wxPaintDC(self)
self.PrepareDC(dc)
if self.image:
dc.DrawBitmap(self.bitmap, 0,0)
---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org
---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org