Saving GCDC information

I am using GCDC to draw translucent triangles on a small canvas. I
want to access this triangle information later on in the program.

None of the other DCs seem to like transparency, so GCDC is my only option.

Here is a snippet of code:
class Canvas(wx.Panel):
  def __init__(self, parent):
    wx.Panel.__init__(self, parent, size=(100,100),
style=wx.BORDER_SIMPLE| wx.BG_STYLE_CUSTOM)
    self._loadTriangles()
    
    self.Bind(wx.EVT_PAINT, self.OnPaint)
  
  def _getTriangle(self):
    p0 = wx.Point(random.randint(0,100), random.randint(0,100))
    p1 = wx.Point(random.randint(0,100), random.randint(0,100))
    p2 = wx.Point(random.randint(0,100), random.randint(0,100))
    brushclr = wx.Colour(random.randint(0, 255), random.randint(0, 255),
random.randint(0, 255), random.randint(64,193))
    
    return ([p0, p1, p2], brushclr)
  
  def _loadTriangles(self):
    self.Triangles = []
    self.vTlist = []
    for x in range(5):
      self.Triangles.append(self._getTriangle())
      a, b, c = self.Triangles[-1][0]
                       # triangle is a class defined earlier
      self.vTlist.append(triangle(vector(a.x, a.y), vector(b.x, b.y),
vector(c.x, c.y)))

  def OnPaint(self, event):
    pdc = wx.PaintDC(self)
    ### taken from the Demo
    try:
      dc = wx.GCDC(pdc)
    except:
      dc = pdc
    dc.SetPen(wx.Pen(wx.Colour(0 , 0,0, 0)))
    
    for points, color in self.Triangles:
      dc.SetBrush(wx.Brush(color))
      dc.DrawPolygon(points)
    
    rect = wx.Rect()
    rect.SetSize(self.GetSize())
    self.buffer = dc.GetAsBitmap(rect) ## this is line 91

The code breaks at this point:

Traceback (most recent call last):
  File "triangledrawing.py", line 91, in OnPaint
    self.buffer = dc.GetAsBitmap(rect)
  File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_gdi.py",
line 3541, in GetAsBitmap
    return _gdi_.DC_GetAsBitmap(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "Ok() && (rect.x >= 0) &&
(rect.y >= 0) && (rect.x+rect.width <= GetWidth()) &&
(rect.y+rect.height <= GetHeight())" failed at
..\..\src\msw\bitmap.cpp(1087) in wxBitmap::GetSubBitmapOfHDC():
Invalid bitmap or bitmap region

I have tried setting the rectangle using a tuple (0, 0, 100, 100) or
smaller rectangles, and I get the same error message.

All I want to do is grab the image data generated on the dc. I've
trolled the docs but can't see how to save a bitmap, transfer the data
to a MemoryDC, or use a GraphicsContext to store the data.

Any suggestions?

···

--
Josh English
Joshua.R.English@gmail.com
http://joshenglish.livejournal.com

Josh,

Try:
dc = wx.ClientDC(self)
memDC = wx.MemoryDC()
x,y = self.GetClientSizeTuple()
bitmap = wx.EmptyBitmap(x, y, -1)
memDC.SelectObject(bitmap)
memDC.Blit(0, 0, x, y, dc, 0, 0)
memDC.SelectObject(wx.NullBitmap)

Then you can use the bitmap later or save it to a file:

bitmap.SaveFile(fileName, wx.BITMAP_TYPE_PNG)

Fahri

···

On Tue, Dec 23, 2008 at 8:50 PM, Josh English <joshua.r.english@gmail.com> wrote:

I am using GCDC to draw translucent triangles on a small canvas. I
want to access this triangle information later on in the program.

None of the other DCs seem to like transparency, so GCDC is my only option.

Here is a snippet of code:
class Canvas(wx.Panel):
       def __init__(self, parent):
               wx.Panel.__init__(self, parent, size=(100,100),
style=wx.BORDER_SIMPLE| wx.BG_STYLE_CUSTOM)
               self._loadTriangles()

               self.Bind(wx.EVT_PAINT, self.OnPaint)

       def _getTriangle(self):
               p0 = wx.Point(random.randint(0,100), random.randint(0,100))
               p1 = wx.Point(random.randint(0,100), random.randint(0,100))
               p2 = wx.Point(random.randint(0,100), random.randint(0,100))
               brushclr = wx.Colour(random.randint(0, 255), random.randint(0, 255),
random.randint(0, 255), random.randint(64,193))

               return ([p0, p1, p2], brushclr)

       def _loadTriangles(self):
               self.Triangles =
               self.vTlist =
               for x in range(5):
                       self.Triangles.append(self._getTriangle())
                       a, b, c = self.Triangles[-1][0]
                      # triangle is a class defined earlier
                       self.vTlist.append(triangle(vector(a.x, a.y), vector(b.x, b.y),
vector(c.x, c.y)))

       def OnPaint(self, event):
               pdc = wx.PaintDC(self)
               ### taken from the Demo
               try:
                       dc = wx.GCDC(pdc)
               except:
                       dc = pdc
               dc.SetPen(wx.Pen(wx.Colour(0 , 0,0, 0)))

               for points, color in self.Triangles:
                       dc.SetBrush(wx.Brush(color))
                       dc.DrawPolygon(points)

               rect = wx.Rect()
               rect.SetSize(self.GetSize())
               self.buffer = dc.GetAsBitmap(rect) ## this is line 91

The code breaks at this point:

Traceback (most recent call last):
File "triangledrawing.py", line 91, in OnPaint
   self.buffer = dc.GetAsBitmap(rect)
File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_gdi.py",
line 3541, in GetAsBitmap
   return _gdi_.DC_GetAsBitmap(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "Ok() && (rect.x >= 0) &&
(rect.y >= 0) && (rect.x+rect.width <= GetWidth()) &&
(rect.y+rect.height <= GetHeight())" failed at
..\..\src\msw\bitmap.cpp(1087) in wxBitmap::GetSubBitmapOfHDC():
Invalid bitmap or bitmap region

I have tried setting the rectangle using a tuple (0, 0, 100, 100) or
smaller rectangles, and I get the same error message.

All I want to do is grab the image data generated on the dc. I've
trolled the docs but can't see how to save a bitmap, transfer the data
to a MemoryDC, or use a GraphicsContext to store the data.

Any suggestions?
--
Josh English
Joshua.R.English@gmail.com
http://joshenglish.livejournal.com
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

This loses the transparency and saves a different image.

I have attached a "working" file that doesn't give me any errors, but
still loses the transparency of the drawn image in the saved file or
the MemoryDC.

triangledrawing.py (4.06 KB)

···

On Tue, Dec 23, 2008 at 8:20 PM, Fahreddın Basegmez <mangabasi@gmail.com> wrote:

On Tue, Dec 23, 2008 at 8:50 PM, Josh English > <joshua.r.english@gmail.com> wrote:

I am using GCDC to draw translucent triangles on a small canvas. I
want to access this triangle information later on in the program.

None of the other DCs seem to like transparency, so GCDC is my only option.

Here is a snippet of code:
class Canvas(wx.Panel):
       def __init__(self, parent):
               wx.Panel.__init__(self, parent, size=(100,100),
style=wx.BORDER_SIMPLE| wx.BG_STYLE_CUSTOM)
               self._loadTriangles()

               self.Bind(wx.EVT_PAINT, self.OnPaint)

       def _getTriangle(self):
               p0 = wx.Point(random.randint(0,100), random.randint(0,100))
               p1 = wx.Point(random.randint(0,100), random.randint(0,100))
               p2 = wx.Point(random.randint(0,100), random.randint(0,100))
               brushclr = wx.Colour(random.randint(0, 255), random.randint(0, 255),
random.randint(0, 255), random.randint(64,193))

               return ([p0, p1, p2], brushclr)

       def _loadTriangles(self):
               self.Triangles =
               self.vTlist =
               for x in range(5):
                       self.Triangles.append(self._getTriangle())
                       a, b, c = self.Triangles[-1][0]
                      # triangle is a class defined earlier
                       self.vTlist.append(triangle(vector(a.x, a.y), vector(b.x, b.y),
vector(c.x, c.y)))

       def OnPaint(self, event):
               pdc = wx.PaintDC(self)
               ### taken from the Demo
               try:
                       dc = wx.GCDC(pdc)
               except:
                       dc = pdc
               dc.SetPen(wx.Pen(wx.Colour(0 , 0,0, 0)))

               for points, color in self.Triangles:
                       dc.SetBrush(wx.Brush(color))
                       dc.DrawPolygon(points)

               rect = wx.Rect()
               rect.SetSize(self.GetSize())
               self.buffer = dc.GetAsBitmap(rect) ## this is line 91

The code breaks at this point:

Traceback (most recent call last):
File "triangledrawing.py", line 91, in OnPaint
   self.buffer = dc.GetAsBitmap(rect)
File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_gdi.py",
line 3541, in GetAsBitmap
   return _gdi_.DC_GetAsBitmap(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "Ok() && (rect.x >= 0) &&
(rect.y >= 0) && (rect.x+rect.width <= GetWidth()) &&
(rect.y+rect.height <= GetHeight())" failed at
..\..\src\msw\bitmap.cpp(1087) in wxBitmap::GetSubBitmapOfHDC():
Invalid bitmap or bitmap region

I have tried setting the rectangle using a tuple (0, 0, 100, 100) or
smaller rectangles, and I get the same error message.

All I want to do is grab the image data generated on the dc. I've
trolled the docs but can't see how to save a bitmap, transfer the data
to a MemoryDC, or use a GraphicsContext to store the data.

Any suggestions?
--
Josh English
Joshua.R.English@gmail.com
http://joshenglish.livejournal.com
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Josh,

Try:
dc = wx.ClientDC(self)
memDC = wx.MemoryDC()
x,y = self.GetClientSizeTuple()
bitmap = wx.EmptyBitmap(x, y, -1)
memDC.SelectObject(bitmap)
memDC.Blit(0, 0, x, y, dc, 0, 0)
memDC.SelectObject(wx.NullBitmap)

Then you can use the bitmap later or save it to a file:

bitmap.SaveFile(fileName, wx.BITMAP_TYPE_PNG)

Fahri
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

--
Josh English
Joshua.R.English@gmail.com

Josh English wrote:

I have attached a "working" file that doesn't give me any errors, but
still loses the transparency of the drawn image in the saved file or
the MemoryDC.

I think that's because the standard BitMap does not have an alpha channel -- I"m sorry I can't remember right now how to get an alpha Bitmap, but it can be done -- some searching of this list should help you.

You may also want to take a look at FloatCanvas2 (FloatCanvas 1 does not do alpha either)-- it could be very helpful for you:

http://svn.wxwidgets.org/viewvc/wx/wxPython/3rdParty/branches/FloatCanvas/SOC2008_FloatCanvas/

It's new, but powerful. You can get questions answered on the FloatCanvas list:

http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Josh,

You may want to take a look at BitmapFromBufferRGBA. I think it had
some cross platform issues Mac/Windows vs Linux if I remember
correctly.

Fahri

···

2008/12/24 Josh English <joshua.r.english@gmail.com>:

This loses the transparency and saves a different image.

I have attached a "working" file that doesn't give me any errors, but
still loses the transparency of the drawn image in the saved file or
the MemoryDC.

On Tue, Dec 23, 2008 at 8:20 PM, Fahreddın Basegmez <mangabasi@gmail.com> wrote:

On Tue, Dec 23, 2008 at 8:50 PM, Josh English >> <joshua.r.english@gmail.com> wrote:

I am using GCDC to draw translucent triangles on a small canvas. I
want to access this triangle information later on in the program.

None of the other DCs seem to like transparency, so GCDC is my only option.

Here is a snippet of code:
class Canvas(wx.Panel):
       def __init__(self, parent):
               wx.Panel.__init__(self, parent, size=(100,100),
style=wx.BORDER_SIMPLE| wx.BG_STYLE_CUSTOM)
               self._loadTriangles()

               self.Bind(wx.EVT_PAINT, self.OnPaint)

       def _getTriangle(self):
               p0 = wx.Point(random.randint(0,100), random.randint(0,100))
               p1 = wx.Point(random.randint(0,100), random.randint(0,100))
               p2 = wx.Point(random.randint(0,100), random.randint(0,100))
               brushclr = wx.Colour(random.randint(0, 255), random.randint(0, 255),
random.randint(0, 255), random.randint(64,193))

               return ([p0, p1, p2], brushclr)

       def _loadTriangles(self):
               self.Triangles =
               self.vTlist =
               for x in range(5):
                       self.Triangles.append(self._getTriangle())
                       a, b, c = self.Triangles[-1][0]
                      # triangle is a class defined earlier
                       self.vTlist.append(triangle(vector(a.x, a.y), vector(b.x, b.y),
vector(c.x, c.y)))

       def OnPaint(self, event):
               pdc = wx.PaintDC(self)
               ### taken from the Demo
               try:
                       dc = wx.GCDC(pdc)
               except:
                       dc = pdc
               dc.SetPen(wx.Pen(wx.Colour(0 , 0,0, 0)))

               for points, color in self.Triangles:
                       dc.SetBrush(wx.Brush(color))
                       dc.DrawPolygon(points)

               rect = wx.Rect()
               rect.SetSize(self.GetSize())
               self.buffer = dc.GetAsBitmap(rect) ## this is line 91

The code breaks at this point:

Traceback (most recent call last):
File "triangledrawing.py", line 91, in OnPaint
   self.buffer = dc.GetAsBitmap(rect)
File "C:\Python26\lib\site-packages\wx-2.8-msw-unicode\wx\_gdi.py",
line 3541, in GetAsBitmap
   return _gdi_.DC_GetAsBitmap(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "Ok() && (rect.x >= 0) &&
(rect.y >= 0) && (rect.x+rect.width <= GetWidth()) &&
(rect.y+rect.height <= GetHeight())" failed at
..\..\src\msw\bitmap.cpp(1087) in wxBitmap::GetSubBitmapOfHDC():
Invalid bitmap or bitmap region

I have tried setting the rectangle using a tuple (0, 0, 100, 100) or
smaller rectangles, and I get the same error message.

All I want to do is grab the image data generated on the dc. I've
trolled the docs but can't see how to save a bitmap, transfer the data
to a MemoryDC, or use a GraphicsContext to store the data.

Any suggestions?
--
Josh English
Joshua.R.English@gmail.com
http://joshenglish.livejournal.com
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Josh,

Try:
dc = wx.ClientDC(self)
memDC = wx.MemoryDC()
x,y = self.GetClientSizeTuple()
bitmap = wx.EmptyBitmap(x, y, -1)
memDC.SelectObject(bitmap)
memDC.Blit(0, 0, x, y, dc, 0, 0)
memDC.SelectObject(wx.NullBitmap)

Then you can use the bitmap later or save it to a file:

bitmap.SaveFile(fileName, wx.BITMAP_TYPE_PNG)

Fahri
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

--
Josh English
Joshua.R.English@gmail.com
http://joshenglish.livejournal.com

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users