I am writing a program that creates and displays an image based upon a
numpy array. Ideally I would like to have a 32bit int (0xAARRGGBB) in
each element of the array, and convert that to a bitmap. To get
familiar with drawing to the screen I followed an example and came up
with the following code. I'm trying to do a trivial example of drawing
a 1x1 bitmap and drawing (blitting?) that to the DC. It's turning out
not to be so trivial however as the MakeCustomBitmap function in the
below code doesn't work.
The wx.Bitmap documentation isn't helping me out to much on this issue
as:
1) I don't know how 'A simple sequence of RGB bytes' is
represented.
2) Any 'Sequence of 32-bit values' seems to be giving me a black
pixel.
Any suggestions?
···
===
CopyFromBuffer(self, data, format=BitmapBufferFormat_RGB, stride=-1)
Copy data from a buffer object to replace the bitmap pixel data.
Default format is plain RGB, but other formats are now supported as
well. The following symbols are used to specify the format of the
bytes in the buffer:
============================= ================================
wx.BitmapBufferFormat_RGB A simple sequence of RGB bytes
wx.BitmapBufferFormat_RGBA A simple sequence of RGBA bytes
wx.BitmapBufferFormat_ARGB32 A sequence of 32-bit values in
native
endian order, with alpha in the
upper
8 bits, followed by red, green, and
blue.
wx.BitmapBufferFormat_RGB32 Same as above but the alpha byte
is ignored.
============================= ================================
=================================
import wx
import array
class SketchFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "Sketch Frame",size=
(350,350))
self.sketch = ScrolledCanvas(self, -1)
class ScrolledCanvas(wx.ScrolledWindow):
def __init__(self, parent, id = -1, size = wx.DefaultSize):
wx.ScrolledWindow.__init__(self, parent, id, (0, 0), size=size,
style=wx.SUNKEN_BORDER)
self.maxWidth = 100
self.maxHeight = 100
self.SetBackgroundColour("WHITE")
self.SetVirtualSize((self.maxWidth, self.maxHeight))
self.SetScrollRate(20,20)
self.bmp = None
# Initialize the buffer bitmap. No real DC is needed at this point.
self.buffer = wx.EmptyBitmap(self.maxWidth, self.maxHeight)
dc = wx.BufferedDC(None, self.buffer)
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
self.bmp = self.MakeCustomBitmap()
self.DoDrawing(dc)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBack)
def MakeCustomBitmap(self):
"""
Make a bitmap with a single pixel
"""
bmp = wx.EmptyBitmap(1, 1)
yellow = array.array('I', [255, 255, 000])
yellow2 = '255255000'
yellow3 = 'FFFF00'
# This throws a runtime exception:
# 'RuntimeError: Failed to gain raw access to bitmap data.'
#bmp.CopyFromBuffer(yellow, wx.BitmapBufferFormat_RGB32)
# This gives me a bitmap, but the one pixel is black on the screen =
(
bmp.CopyFromBuffer(yellow, wx.BitmapBufferFormat_RGB32)
return bmp
def OnEraseBack(self, event):
pass # do nothing to avoid flicker
def OnPaint(self, event):
# Create a buffered paint DC. It will create the real
# wx.PaintDC and then blit the bitmap to it when dc is
# deleted. Since we don't need to draw anything else
# here that's all there is to it.
dc = wx.BufferedPaintDC(self, self.buffer, wx.BUFFER_VIRTUAL_AREA)
def DoDrawing(self, dc, printing=False):
dc.BeginDrawing()
dc.DrawBitmap(self.bmp, 0, 0, False)
dc.EndDrawing()