Resize wx.Bitmap inside wx.Panel

Hello,
I would like to use wxPython to create simple images consisting of graphical
primitives, save them as *.PNG files, and visualize them inside a wx.Frame
on a wx.Panel. I have written a small sample program to demonstrate with a
simple example how that could be achieved. Even eith this simple program,
there are two things that I don't understand.
1. The space that is reserved on the wx.Panel to display the contents of the
wx.DC is the size of bitmap that sits "behind" the wx.MemoryDC. In lines 33
and 34, I try to change the size of the bitmap, but that seems to be ignored
when the wx.Panel is finally drawn. All that I see is the area that
corresponds to the bitmaps original size. How can I adjust the size of the
bitmap or the device context after creation?
2. When I try to change the size of the bitmap, I get an empty *.PNG file
without drawing. When I comment out these two lines, I get the expected
content in the created PNG. The contents of the wx.Panel are the same in
both cases. What is the reason for the different ouput in the file?
Here is my sample program:
import wx

···

#______________________________________________

class BitmapPanel(wx.Panel):
    def __init__(self,id,parent,virtualDC):
        wx.Panel.__init__(self,parent,id)
        self.virtualDC = virtualDC
        self.Bind(wx.EVT_PAINT,self.OnPaint)

    def OnPaint(self,event):
        dc = wx.PaintDC(self)
        dc.Blit(0,0,1024,768,self.virtualDC,0,0)
#______________________________________________

class VirtualBitmap(wx.MemoryDC):
    def __init__(self,width=200,height=200):
        wx.MemoryDC.__init__(self)
        self.width = width
        self.height = height
        self.bitmap = wx.EmptyBitmap(width,height)
        self.SelectObject(self.bitmap)
        self.Clear()

    def SaveFile(self,name,bmptype=wx.BITMAP_TYPE_PNG):
        return self.bitmap.SaveFile(name,bmptype)
#______________________________________________

def DrawGrid(panel):
    border = 5
    size = 24
    lineNumber = 30
    panel.bitmap.SetWidth(lineNumber*size+border*2)
    panel.bitmap.SetHeight(lineNumber*size+border*2)

    for i in range(lineNumber):
        #draw vertical lines
       
panel.DrawLine(border+i*size,border,border+i*size,border+(lineNumber-1)*size)
        #draw horizontal lines
       
panel.DrawLine(border,border+i*size,border+(lineNumber-1)*size,border+i*size)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    width = 500
    height = 500
    img = VirtualBitmap(width,height)
    brush = wx.Brush(wx.Colour(120,120,120),wx.SOLID)
    pen = wx.Pen(wx.Colour(120,120,120),3,wx.SOLID)
    img.SetBrush(brush)
    img.SetPen(pen)
    pen.SetCap(wx.CAP_BUTT)
    DrawGrid(img)
    bool = img.SaveFile("wxBitmap.png",wx.BITMAP_TYPE_PNG)
    if not bool:
        print "Couldn't save"
    frame = wx.Frame(None,-1,"View")
    panel = BitmapPanel(-1,frame,img)
    panel.SetSize((1024,768))
    frame.Fit()
    frame.Show(True)
    app.MainLoop()
I work with Python 2.3.4, wxPython 2.6.0.1 on WindowsME.

Many thanks for your explanations and hints
Piet

--
Geschenkt: 3 Monate GMX ProMail gratis + 3 Ausgaben stern gratis
++ Jetzt anmelden & testen ++ http://www.gmx.net/de/go/promail ++

I don't think you can change the size of the bitmap after it has been created. Instead you should add a method that creates a new bitmap of the new size and then selects it into the DC.

···

pit.grinja@gmx.de wrote:

Hello,
I would like to use wxPython to create simple images consisting of graphical
primitives, save them as *.PNG files, and visualize them inside a wx.Frame
on a wx.Panel. I have written a small sample program to demonstrate with a
simple example how that could be achieved. Even eith this simple program,
there are two things that I don't understand.
1. The space that is reserved on the wx.Panel to display the contents of the
wx.DC is the size of bitmap that sits "behind" the wx.MemoryDC. In lines 33
and 34, I try to change the size of the bitmap, but that seems to be ignored
when the wx.Panel is finally drawn. All that I see is the area that
corresponds to the bitmaps original size. How can I adjust the size of the
bitmap or the device context after creation?
2. When I try to change the size of the bitmap, I get an empty *.PNG file
without drawing. When I comment out these two lines, I get the expected
content in the created PNG. The contents of the wx.Panel are the same in
both cases. What is the reason for the different ouput in the file?
Here is my sample program:

def DrawGrid(panel):
    border = 5
    size = 24
    lineNumber = 30
    panel.bitmap.SetWidth(lineNumber*size+border*2)
    panel.bitmap.SetHeight(lineNumber*size+border*2)

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Hello,
I would like to use wxPython to create simple images consisting of graphical
primitives, save them as *.PNG files, and visualize them inside a wx.Frame
on a wx.Panel.

Have you looked in the Wiki at:

http://wiki.wxpython.org/index.cgi/DoubleBufferedDrawing
http://wiki.wxpython.org/index.cgi/wxStaticBitmap

they might be some help.

1. The space that is reserved on the wx.Panel to display the contents of the
wx.DC is the size of bitmap that sits "behind" the wx.MemoryDC. In lines 33
and 34, I try to change the size of the bitmap, but that seems to be ignored
when the wx.Panel is finally drawn.

I think Robin already mentioner this, you need to make a new bitmap, rather than re-sizing one.

A few comments in your code.

class BitmapPanel(wx.Panel):
    def __init__(self,id,parent,virtualDC):

The convention is usually: (self, parent, id,....)

        wx.Panel.__init__(self,parent,id)
        self.virtualDC = virtualDC
        self.Bind(wx.EVT_PAINT,self.OnPaint)

It's generally not recommended to keep a Memory DC around. You can just keep the wx.bitmap around, and re-create the DC when you need it.

    def OnPaint(self,event):
        dc = wx.PaintDC(self)
        dc.Blit(0,0,1024,768,self.virtualDC,0,0)

It seems odd to hard-code a size in here.

class VirtualBitmap(wx.MemoryDC):
    def __init__(self,width=200,height=200):
        wx.MemoryDC.__init__(self)
        self.width = width
        self.height = height
        self.bitmap = wx.EmptyBitmap(width,height)
        self.SelectObject(self.bitmap)
        self.Clear()

    def SaveFile(self,name,bmptype=wx.BITMAP_TYPE_PNG):
        return self.bitmap.SaveFile(name,bmptype)

I'm not sure it's worth it to have a class here. All you need is a Bitmap. Your BitmapPanel can have a method that creates the bitmap, and sets up the DC for it.

What the heck, Here's how I'd do this:

-Chris

BitmapTest.py (2.84 KB)

···

pit.grinja@gmx.de wrote:

Chris Barker wrote:

What the heck, Here's how I'd do this:

Somehow I knew that was coming. :wink: Thanks Chris!

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!