resize an image, how to clear the background ?

hello,

I've an image on a panel,
and the panel fills the complete frame.
(This is just a test, the idea is to put the image in a pane of wx.AUI)

Now when the frame is resized, the image should be redrawn with the correct aspect ratio.
For the image part that works,
but if the image shrinks in one direction,
it leaves garbage in the background of the panel.

At the end of resize, I already call these methods,
    self.panel.ClearBackground()
    self.panel.Refresh(True)
but doesn't seem to help.

How should I clear the panel background after a resize ?

thanks,
Stef Mientki

Het UMC St Radboud staat geregistreerd bij de Kamer van Koophandel in het handelsregister onder nummer 41055629.
The Radboud University Nijmegen Medical Centre is listed in the Commercial Register of the Chamber of Commerce under file number 41055629.

test_image_form.py (1.62 KB)

Vippi_Bricks.png

Peter Decker wrote:

  

hello,

I've an image on a panel,
and the panel fills the complete frame.
(This is just a test, the idea is to put the image in a pane of wx.AUI)

Now when the frame is resized, the image should be redrawn with the
correct aspect ratio.
For the image part that works,
but if the image shrinks in one direction,
it leaves garbage in the background of the panel.

At the end of resize, I already call these methods,
    self.panel.ClearBackground()
    self.panel.Refresh(True)
but doesn't seem to help.

How should I clear the panel background after a resize ?
    
You should take a look at the dImage class of Dabo. The code to do
what you need is all there; this class is one of the reasons I
switched to Dabo in the first place. In fact, this class was one of
the central parts of the Dabo session at PyCon this year:
  

thanks Peter,
but do you really think, that for simple background redrawing problem,
I would switch to a complete other package ?
(of which the demo even didn't run on my PC :wink:

cheers,
Stef

Het UMC St Radboud staat geregistreerd bij de Kamer van Koophandel in het handelsregister onder nummer 41055629.
The Radboud University Nijmegen Medical Centre is listed in the Commercial Register of the Chamber of Commerce under file number 41055629.

···

On Nov 23, 2007 7:37 AM, Stef Mientki <s.mientki@ru.nl> wrote:

Hi Stef,

hello,

I've an image on a panel,
and the panel fills the complete frame.
(This is just a test, the idea is to put the image in a pane of wx.AUI)

Now when the frame is resized, the image should be redrawn with the
correct aspect ratio.
For the image part that works,
but if the image shrinks in one direction,
it leaves garbage in the background of the panel.

At the end of resize, I already call these methods,
   self.panel.ClearBackground()
   self.panel.Refresh(True)
but doesn't seem to help.

How should I clear the panel background after a resize ?

Can you try the attached modified version of your file and see if it
does what you need?

HTH.

import wx

# ***********************************************************************
# ***********************************************************************
class Test_Form(wx.MiniFrame):

    def __init__(self):

        wx.MiniFrame.__init__(self, None, style=wx.DEFAULT_FRAME_STYLE)

        self.panel = wx.Panel(self)
        self.image = wx.Image('Vippi_Bricks.png', wx.BITMAP_TYPE_PNG)
        self.bmp = None

        self.panel.Bind(wx.EVT_SIZE, self.OnSize)
        self.panel.Bind(wx.EVT_PAINT, self.OnPaint)
        self.panel.Bind(wx.EVT_ERASE_BACKGROUND, self.OnErase)

        self.Show()

    def OnPaint(self, event):

        if self.bmp is None:
            self.Resize()

        dc = wx.BufferedPaintDC(self.panel)
        dc.Clear()

        dc.DrawBitmap(self.bmp, 0, 0)

    def OnErase(self, event):

        pass

    def OnSize(self, event):

        self.Resize()
        self.Refresh()
        event.Skip()

    def Resize(self):

        w, h = self.image.GetWidth(), self.image.GetHeight()
        a1, a2 = self.panel.GetClientSize()
        a1 = 1.0*a1/w
        a2 = 1.0*a2/h
        a = min(a1, a2)

        self.bmp = self.image.Scale(int(a*w), int(a*h)).ConvertToBitmap()

# ***********************************************************************
# ***********************************************************************
class Test_App (wx.App):

    def OnInit (self):

        My_Form = Test_Form()
        return True

# ***********************************************************************

# ***********************************************************************
# ***********************************************************************

if __name__ == "__main__":
    My_App = Test_App(False)
    My_App.MainLoop()

# ***********************************************************************

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

···

On Nov 23, 2007 12:37 PM, Stef Mientki wrote:

Peter Decker wrote:

···

On Nov 23, 2007 8:29 AM, Stef Mientki <s.mientki@ru.nl> wrote:

thanks Peter,
but do you really think, that for simple background redrawing problem,
I would switch to a complete other package ?
(of which the demo even didn't run on my PC :wink:
    
Not at all, since I remember you having unusual problems getting Dabo
to run on your system. I only suggested that you look at the code to
see how they did things in the hope that it might give you an idea how
to get your code working. But I see that Andrea has already figured it
out for you.
  

Anyway thanks Peter !!
cheers,
Stef

Het UMC St Radboud staat geregistreerd bij de Kamer van Koophandel in het handelsregister onder nummer 41055629.
The Radboud University Nijmegen Medical Centre is listed in the Commercial Register of the Chamber of Commerce under file number 41055629.

The erase does nothing because the entire image is re-drawn and
re-buffered with each paint.

This actually isn't a super-good way to do it. You can get what you
want just by using the wx.FULL_REPAINT_ON_RESIZE flag (instead of the
buffered paint dc), and using the BG_STYLE_CUSTOM flag, which allows
for more efficient self-drawn backgrounds under Gtk.

See attached for a code sample with comments.

t.py (1.78 KB)

···

On Nov 23, 2007 8:51 AM, Stef Mientki <s.mientki@ru.nl> wrote:

Although the code works perfect,
I'm puzzled with a few lines of code,
which I don't understand at all.
> import wx
>
> # ***********************************************************************
> # ***********************************************************************
> class Test_Form(wx.MiniFrame):
>
> def __init__(self):
>
> wx.MiniFrame.__init__(self, None, style=wx.DEFAULT_FRAME_STYLE)
>
> self.panel = wx.Panel(self)
> self.image = wx.Image('Vippi_Bricks.png', wx.BITMAP_TYPE_PNG)
> self.bmp = None
>
> self.panel.Bind(wx.EVT_SIZE, self.OnSize)
> self.panel.Bind(wx.EVT_PAINT, self.OnPaint)
> self.panel.Bind(wx.EVT_ERASE_BACKGROUND, self.OnErase)
>
> self.Show()
>
>
> def OnPaint(self, event):
>
> if self.bmp is None:
> self.Resize()
>
> dc = wx.BufferedPaintDC(self.panel)
> dc.Clear()
>
> dc.DrawBitmap(self.bmp, 0, 0)
>
>
> def OnErase(self, event):
> pass
>
>
So the Erase does nothing ???
But that must be wrong,
because if I remove it the image begins to flicker when I resize it.
Or is the function of OnErase,
to block the erasing ?