Table of Contents:

Converting Between PIL image, wx.Bitmap and wx.Image

Toggle line numbers
   1 # Tested with wxPython 2.3.4.2 and PIL 1.1.3.
   2 import wx
   3 import Image             # PIL module. Only if you use the PIL library.
   4 
   5 def WxBitmapToPilImage( myBitmap ) :
   6     return WxImageToPilImage( WxBitmapToWxImage( myBitmap ) )
   7 
   8 def WxBitmapToWxImage( myBitmap ) :
   9     return wx.ImageFromBitmap( myBitmap )
  10 
  11 #-----
  12 
  13 def PilImageToWxBitmap( myPilImage ) :
  14     return WxImageToWxBitmap( PilImageToWxImage( myPilImage ) )
  15 
  16 def PilImageToWxImage( myPilImage ):
  17     myWxImage = wx.EmptyImage( myPilImage.size[0], myPilImage.size[1] )
  18     myWxImage.SetData( myPilImage.convert( 'RGB' ).tostring() )
  19     return myWxImage
  20 
  21 # Or, if you want to copy any alpha channel, too (available since wxPython 2.5)
  22 # The source PIL image doesn't need to have alpha to use this routine.
  23 # But, a PIL image with alpha is necessary to get a wx.Image with alpha.
  24 
  25 def PilImageToWxImage( myPilImage, copyAlpha=True ) :
  26 
  27     hasAlpha = myPilImage.mode[ -1 ] == 'A'
  28     if copyAlpha and hasAlpha :  # Make sure there is an alpha layer copy.
  29 
  30         myWxImage = wx.EmptyImage( *myPilImage.size )
  31         myPilImageCopyRGBA = myPilImage.copy()
  32         myPilImageCopyRGB = myPilImageCopyRGBA.convert( 'RGB' )    # RGBA --> RGB
  33         myPilImageRgbData =myPilImageCopyRGB.tostring()
  34         myWxImage.SetData( myPilImageRgbData )
  35         myWxImage.SetAlphaData( myPilImageCopyRGBA.tostring()[3::4] )  # Create layer and insert alpha values.
  36 
  37     else :    # The resulting image will not have alpha.
  38 
  39         myWxImage = wx.EmptyImage( *myPilImage.size )
  40         myPilImageCopy = myPilImage.copy()
  41         myPilImageCopyRGB = myPilImageCopy.convert( 'RGB' )    # Discard any alpha from the PIL image.
  42         myPilImageRgbData =myPilImageCopyRGB.tostring()
  43         myWxImage.SetData( myPilImageRgbData )
  44 
  45     return myWxImage
  46 
  47 #-----
  48 
  49 def imageToPil( myWxImage ):
  50     myPilImage = Image.new( 'RGB', (myWxImage.GetWidth(), myWxImage.GetHeight()) )
  51     myPilImage.fromstring( myWxImage.GetData() )
  52     return myPilImage
  53 
  54 def WxImageToWxBitmap( myWxImage ) :
  55     return myWxImage.ConvertToBitmap()

But, wait ... There's more ! There are two kinds of transparency that a wx.Image or wx.Bitmap can have: 1) Every pixel is either completely transparent or completely opaque. This binary transparency is a transparency mask. 2) Each pixel can have a variable amount of transparency from completely transparent to completely opaque. The amount of transparency each pixel has is defined by a value from 0 to 255. This is alpha transparency. For example, a GIF file may have a transparency mask, or no transparency at all. A PNG file, however, may have one of a transparency mask, alpha transparency or neither. In comparison, JPG files cannot have any kind of transparency.

Reading Image Files

Reading an image file into a wx.Bitmap :

    wxBitmap = wx.EmptyBitmap( 12, 34 )     # Create a dummy image
    wxBitmap.LoadFile( filename, wx.BITMAP_TYPE_ANY )

To determine whether the bitmap has a mask or alpha transparency :

    bitmapHasMask  = wxBitmap.GetMask()    # "GetMask" NOT "HasMask" !
    bitmapHasAlpha = wxBitmap.HasAlpha()

Reading a image file into a wx.Image :

    wxBitmap = wx.EmptyBitmap( 12, 34 )     # Create a dummy image
    wxBitmap.LoadFile( filename, wx.BITMAP_TYPE_ANY )

To determine whether the bitmap has a mask or alpha transparency :

    imageHasMask  = wxImage.HasMask()    # "HasMask" NOT "GetMask" !
    imageHasAlpha = wxImage.HasAlpha()

Reading an image file into a Python Image :

    pyImage = Image.open( filename )

To check if a PIL image has alpha transparency :

    pyImageHasAlpha = pyImage.mode[ -1 ] == 'A'

}When PIL reads in a PNG file with a mask, it automatically converts the mask into alpha transparency whose values are either 0 for completely transparent or 255 completely opaque.

Converting a Transparency Mask into Alpha Transparency

PIL image transparency can only be the alpha kind, but a wx.Bitmap and a wx.Image could have either kind. To convert a wx.Image transparency mask in to alpha transparency :

    imageHasMask  = wxImage.HasMask()
    if wxImage.HasMask() :
        wxImage.InitAlpha()

You can use the flag parameters addAlphaLayer and delAlphaLayer to optionally : 1) Create an image with a alpha transparency when a source image had none (addAlphaLayer=True), or conversely, 2) Prevent alpha from automatically being created when the source image has one (delAlphaLayer=True).

ImgConv.py

This module also contains six conversion functions, but it automatically preserves any transparency that is present in the input images:

WxBitmapFromPilImage()
WxImageFromPilImage()

WxBitmapFromWxImage()
PilImageFromWxImage()

WxImageFromWxBitmap()
PilImageFromWxBitmap()

Conversions Between wx.Image, wx.Bitmap, wx.Cursor, wx.Icon and String Data

wx.Image to wx.Bitmap :

myWxBitmap = myWxImage.ConvertToBitmap()

or :

myWxBitmap = wxBitmapFromImage( myWxImage )

wxImage to String Data :

myStringData = myWxImage.GetData()

Returns a Python string of binary data of length (width * height * 3).

Convert String Data to a wx.Image :

image = wxImage()
image.SetData( pythonStringData )

where pythonStringData is a Python string of binary data of length (width * height * 3).

Python string of binary data to a wx.Bitmap : Go through wx.Image to get a wx.Bitmap.

DATA to a wx.Icon : Should be possible, but I don't see an overloaded-constructor name for it.

wx.Icon to wxBitmap :

myWxBitmap = wx.EmptyBitmap( myIcon.GetWidth(), myIcon.GetHeight() )
myWxBitmap.CopyFromIcon( myIcon )

wxBitmap to DATA or wxImage :

Python string of binary data or wx.Image to wxCursor :

wx.Icon to Python string of binary data or wx.Image :

To allow for editing of icons, this would be required.

wxCursor to Python string of binary data or wxImage :

Again, to allow for editing cursors. Would also need methods to get the current hot spot. wxImage to wxIcon -- See DATA to wxIcon above, either one would be fine, but would be nice to have the complete set.ImgConv.py

PIL (Python Imaging Library)

Toggle line numbers
   1 import Image
   2 
   3 def BitmapFromFile( self ) :
   4 
   5         source = Image.open( r"Z:\mcfport\portfoli\full\claire.jpg" )
   6         image = wx.EmptyImage( *source.size )
   7         image.SetData( source.convert( 'RGB' ).tostring() )
   8 
   9         # if the image has an alpha channel, you can set it with this line:
  10         image.SetAlphaData(source.convert( 'RGBA' ).tostring()[3::4])
  11         bitmap = image.ConvertToBitmap()      # or:   bitmap = wx.BitmapFromImage( image )
  12         return bitmap

Note: If a GIF file with a mask is read, PIL will automatically convert it to alpha transparency. This is suitable for most purposes.

NumPy

Toggle line numbers
   1 import wx, numpy
   2 
   3 def GetBitmap( self, width=32, height=32, colour = (0,0,0) ):
   4         array = numpy.zeros( (height, width, 3),'uint8')
   5         array[:,:,] = colour
   6         image = wx.EmptyImage(width,height)
   7         image.SetData( array.tostring())
   8         wxBitmap = image.ConvertToBitmap()   # OR:  wx.BitmapFromImage(image)
   9         return wxBitmap

Slicing

NumPy's slicing notation, for our purposes, works as follows:  [ rowStart: rowEnd, columnStart: columnEnd, colourPlanes ]  To assign a single colour to the entire image:  array[:,:] = (r,g,b)  To assign a value to the entire red bit plane:  array[:,:,0] = 255  To assign a colour to the first row:  array[ 0 ] = (r,g,b ) 

Examples

This example shows use of NumPy's (extended) slicing notation to alter an in-memory image. Note that the slice notation allows for standard negative-value index semantics. Also note the accomodating nature of the assignment operation. Assigning a three-tuple to a row sets every value in the row, while assigning a list of three-tuples will set each value individually (and raise an error if the number of items is incorrect).

Toggle line numbers
   1 import wx, numpy
   2 
   3 def GetBitmap( self, width=32, height=32, colour=(128, 128, 128), border=5, borderColour=(255, 255, 255) ):
   4     """
   5     Creates a bitmap with a border.
   6     """"
   7     array = numpy.zeros( (height, width, 3), 'uint8' )
   8     array[ border:-border, border:-border, : ] = colour
   9     array[ :border, :, : ] = borderColour
  10     array[ -border:, :, : ] = borderColour
  11     array[ :, :border, :] = borderColour
  12     array[ :, -border:, : ] = borderColour
  13     image = wx.EmptyImage( width, height )
  14     image.SetData( array.tostring() )
  15     return image.ConvertToBitmap()    # OR:  wx.BitmapFromImage( image )

This example creates a horizontal gradient between two colours. Note that NumPy is automatically converting from float to uint8 data type in the assignment to array, because of the slice indexing. Without the indexing, array would just get overwritten to point to a different numpy array instead of assigning data within the existing one.

Toggle line numbers
   1 import numpy as np
   2 
   3 def GetBitmap( self, width=640, height=480, leftColour=(255,128,0), rightColour=(64,0,255) ):
   4         """
   5         Create a horizontal gradient
   6         """"
   7         array = np.zeros( (height, width, 3), 'uint8' )
   8 
   9         # alpha is a one dimensional array with a linear gradient from 0.0 to 1.0
  10         alpha = np.linspace( 0., 1., width )
  11 
  12         # This uses alpha to linearly interpolate between leftColour and rightColour
  13         colourGradient = np.outer(alpha, leftColour) + np.outer( (1.-alpha), rightColour )
  14 
  15         # NumPy's broadcasting rules will assign colourGradient to every row of the destination array
  16         array[ :, :, : ] = colourGradient
  17         image = wx.EmptyImage( width, height )
  18         image.SetData( array.tostring() )
  19         wxBitmap = wx.BitmapFromImage( image )    # OR:  image.ConvertToBitmap()
  20         return wxBitmap

Screen Capture

This example captures the client area of a frame to a wxBitmap object (and from there, a file). Note that there is no error checking done here. Should likely use Ok() or something to check each context. I'm not sure what would happen if this were called before the first painting of the screen, likely the context would have the desktop or something in it. Note: code below only captures the client area of the window. Tagore notes that you can get the whole window with a wx.WindowDC and arbitrary parts of the screen with a wx.ScreenDC.

Toggle line numbers
   1 def OnSaveToFile( self, event ):
   2         context = wx.ClientDC( self )
   3         memory = wx.MemoryDC( )
   4         x, y = self.ClientSize
   5         bitmap = wx.EmptyBitmap( x, y, -1 )
   6         memory.SelectObject( bitmap )
   7         memory.Blit( 0, 0, x, y, context, 0, 0)
   8         memory.SelectObject( wx.NullBitmap)
   9         bitmap.SaveFile( 'test.bmp', wx.BITMAP_TYPE_BMP )

A Flexible Screen Capture App

Here's a general screen capture app that first captures the whole primary screen, then captures 4 smaller portions of it. GeneralScreenShotWX.py

Toggle line numbers
   1 def ScreenCapture( captureStartPos, captureSize ):
   2     """
   3     A generalized Desktop screen capture.
   4 
   5     My particular monitor configuration:
   6         wx.Display( 0 ) refers to the extended Desktop display monitor screen.
   7         wx.Display( 1 ) refers to the main     Desktop display monitor screen.
   8 
   9     Any particular Desktop screen size is :
  10         screenRect = wx.Display( n ).GetGeometry()
  11 
  12     Different wx.Display's in a single system are allowed to have
  13     different dimensions.
  14 
  15     """
  16 
  17     # Capture the entire Desktop screen by creating a wx.ScreenDC().
  18     # This DC is just a tool linked to a copy of the bitmap of the entire screen.
  19     # The screen's size may be extended by using multiple monitors.
  20     screenDC = wx.ScreenDC()
  21     screenSizeX, screenSizeY = screenDC.Size      # The screen's dimensions.
  22 
  23     # The size of the Desktop bitmap area to be returned.
  24     captureSizeX, captureSizeY = captureSize
  25 
  26     # Create a new empty (black) destination bitmap with size captureSize.
  27     captureBmap = wx.EmptyBitmap( captureSizeX, captureSizeY )
  28 
  29     # Create a DC tool that is associated with this bitmap.
  30     memDC = wx.MemoryDC( captureBmap )
  31 
  32     # Configure the upcoming Blit call's position and size parameters
  33     #   that will be used to copy a portion of the source screen (Desktop) bitmap
  34     #   into the entire capture destination bitmap.
  35     #
  36     # The upper-left coordinate of the screen bitmap portion to be copied.
  37     screenStartX, screenStartY = captureStartPos
  38 
  39     # Upper-left destination starting coordinate.
  40     captureBmapStartX, captureBmapStartY = (0, 0)
  41 
  42     # Copy (blit, "Block Level Transfer") a portion of the screen bitmap
  43     #   into the returned capture bitmap.
  44     # The bitmap associated with memDC (captureBmap) is the blit destination.
  45     #                                                   # Blit (copy) parameter(s):
  46     memDC.Blit( captureBmapStartX, captureBmapStartY,   # Copy to captureBmap starting here.
  47                 captureSizeX,  captureSizeY,            # Copy an area this size.
  48                 screenDC,                               # Copy from this source DC's bitmap.
  49                 screenStartX, screenStartY )    # Copy from this start coordinate.
  50 
  51     memDC.SelectObject( wx.NullBitmap )     # Finish using this wx.MemoryDC.
  52                                             # Release captureBmap for other uses.
  53     return captureBmap
  54 
  55 #end ScreenCapture def

In the application all five captured wxBitmap objects are saved to PNG files.

The wx.ScreenDC treats the entire Desktop screen as a single seamless conglomerate of all exiting wx.Display() areas. Negative coordinate values relative to the main Desktop screen are allowed. Negative ordinate values must be used to capture any portion of an extension monitor screen to the left of or above the primary monitor screen (the one with the Taskbar). For example, I have two monitors where the extension monitor is configured to be directly above the main monitor. I have set both monitors to 1280x800 resolution. To capture the entire extended screen :

Toggle line numbers
   1     screenWid = wx.SystemSettings.GetMetric( wx.SYS_SCREEN_X )
   2     screenHgt = wx.SystemSettings.GetMetric( wx.SYS_SCREEN_Y )
   3     captureSize = (screenWid, screenHgt*2)
   4     wxBitmap = ScreenCapture( startPos, captureSize )

Other wxPython add-on packages can take arbitrarily sized screen shots, too, such as ImageMagick and PIL. Python Imaging Library:

DesktopScreenShotPIL.py

-- Ray Pasco

Write Text to a Bitmap

Writing text into a bitmap is done by creating a context then using the context's DrawText method to do the actual drawing. A simple example:

Toggle line numbers
   1 import wx
   2 
   3 def SetDcContext( memDC, font=None, color=None ):
   4     if font:
   5         memDC.SetFont( font )
   6     else:
   7         memDC.SetFont( wx.NullFont )
   8 
   9     if color:
  10         memDC.SetTextForeground( color )
  11 
  12 #end def
  13 
  14 def WriteTextOnBitmap( text, bitmap, pos=(0, 0), font=None, color=None) :
  15     """
  16     Simple write into a bitmap doesn't do any checking.
  17     """
  18     memDC = wx.MemoryDC()
  19     SetDcContext( memDC, font, color )
  20     memDC.SelectObject( bitmap )
  21     try:
  22         memDC.DrawText( text, pos[0], pos[1])
  23     except :
  24         pass
  25 
  26     memDC.SelectObject( wx.NullBitmap )
  27 
  28     return bitmap
  29 
  30 #end def

Toggle line numbers
   1 import wx
   2 
   3 MINIMUMFONTSIZE = 4
   4 
   5 def WriteCaptionOnBitmap( text, bitmap, font=None, margins = (2,2), color=None ):
   6     """
   7     Write the given caption (text) into the bitmap
   8     using the font (or default if not given) with the
   9     margins given.  Will try to make sure the text fits
  10     into the bitmap.
  11     """
  12     memory = wx.MemoryDC( )
  13     font = font or memory.GetFont()
  14     textLines = text.split( '\n' )
  15     fit = False
  16     while not fit:
  17         totalWidth=0
  18         totalHeight = 0
  19         setLines = []
  20         for line in textLines:
  21             if line and line[-1] == '\r':
  22                 line = line[:-1]
  23 
  24             width, height = extents = memory.GetTextExtent( line )
  25             totalWidth = max( totalWidth,  width )
  26             totalHeight += height
  27             setLines.append( (line, extents))
  28         #end for
  29 
  30         if (totalWidth > (bitmap.GetWidth()- 2*margins[0])  or  \
  31            (totalHeight > (bitmap.GetHeight()- 2*margins[0]) ) :
  32 
  33             size = font.GetPointSize() - 1
  34             if size < MINIMUMFONTSIZE:
  35                 fit = True # will overdraw!!!
  36             else:
  37                 font.SetPointSize( size )
  38                 memory.SetFont( font )
  39         else:
  40             fit = True
  41         #end if
  42 
  43     #end while
  44 
  45     if not setLines:
  46         return bitmap
  47 
  48     centreX, centreY = (bitmap.GetWidth()/2), (bitmap.GetHeight()/2)
  49     x, y = centreX-(totalWidth/2), centreY-(totalHeight/2)
  50     memory.SelectObject( bitmap )
  51     SetMemDcContext( memory, font, color)
  52     for line, (deltaX, deltaY) in setLines:
  53             x = centreX - (deltaX/2)
  54             memory.DrawText( line, x, y,)
  55             y += deltaY
  56     memory.SelectObject( wxNullBitmap)
  57     return bitmap
  58 
  59 
  60 def SetMemDcContext( memory, font=None, color=None ) :
  61 
  62     if font:
  63         memory.SetFont( font )
  64     else:
  65         memory.SetFont( wx.NullFont )
  66 
  67     if color:
  68         memory.SetTextForeground( color )

Since transparency is a bit tricky, here is another example. (Which unlike the above, works for me).

In this example two bitmaps are created. One is completely white (oldPix) the other one completely black (newPix). Then a red box is drawn on the black bitmap. Now the black color in newPix is masked and then newPix is copied over oldPix (the white one). The result is, that only the red box is copied.

Toggle line numbers
   1 from wxPython.wx import *
   2 
   3 class Test(wxApp):
   4     def OnInit(self):
   5         oldPix  = wx.wxEmptyBitmap(300, 300)
   6         newPix  = wx.wxEmptyBitmap(300, 300)
   7         mem = wxMemoryDC()
   8         mem.SelectObject(oldPix)
   9         mem.Clear()                       # The images have to be cleared
  10         mem.SelectObject(newPix)          # because wxEmptyBitmap only
  11         mem.SetBackground(wxBLACK_BRUSH)  # allocates the space
  12         mem.Clear()
  13 
  14         # We now have a black and a white image
  15         # Next we plot a white box in the middle of the black image
  16 
  17         mem.SetPen(wxRED_PEN)
  18         mem.DrawLines(((100, 200), (100, 100), (200, 100), (200,200), (100,200)))
  19 
  20         mem.SelectObject(oldPix)
  21         newPix.SetMask(wxMaskColour(newPix, wxBLACK))
  22         mem.DrawBitmap(newPix, 0, 0, 1)
  23 
  24         oldPix.SaveFile("oldPix.bmp", wx.wxBITMAP_TYPE_BMP)
  25         newPix.SaveFile("newPix.bmp", wx.wxBITMAP_TYPE_BMP)
  26         return true
  27 
  28 app = Test(0)
  29 app.MainLoop()

This is a complete wxPython app, so just run it and have a look at the created Bitmaps oldPix.bmp and newPix.bmp for the results. -- Nikolai Hlubek

PythonMagick (a 16-bit Imaging Library)

Here is a short but complete PythonMagick/wxPython program. The program uses wxPython GUI, loads an image, displays the image, and does a simple image processing operation (threshold). Various conversions between PythonMagick, PIL, and wxPython images are available on the PythonMagick web site.

See the PythonMagick page for a greater description of PythonMagick.

Note that PythonMagick presently only has a Windows installer.

Toggle line numbers
   1 from wxPython import wx
   2 import PythonMagick
   3 
   4 ID_FILE_OPEN = wx.wxNewId()
   5 ID_FILE_EXIT  = wx.wxNewId()
   6 ID_THRESHOLD = wx.wxNewId()
   7 
   8 class ImagePanel(wx.wxPanel):
   9     def __init__(self, parent, id):
  10         wx.wxPanel.__init__(self, parent, id)
  11         self.image = None  # wxPython image
  12         wx.EVT_PAINT(self, self.OnPaint)
  13 
  14     def display(self, magickimage):
  15         self.image = self.convertMGtoWX(magickimage)
  16         self.Refresh(True)
  17 
  18     def OnPaint(self, evt):
  19         dc = wx.wxPaintDC(self)
  20         if self.image:
  21             dc.DrawBitmap(self.image.ConvertToBitmap(), 0,0)
  22 
  23     def convertMGtoWX(self, magickimage):
  24         img = PythonMagick.Image(magickimage)  # make copy
  25         img.depth = 8        #  change depth only for display
  26         img.magick = "RGB"
  27         data = img.data
  28         wximg = wx.wxEmptyImage(img.columns(), img.rows())
  29         wximg.SetData(data)
  30         return wximg
  31 
  32 
  33 class mtFrame(wx.wxFrame):
  34     def __init__(self, parent, ID, title):
  35         wx.wxFrame.__init__(self, parent, ID, title, wx.wxDefaultPosition, wx.wxSize(500, 400))
  36 
  37         self.iPanel = ImagePanel(self, -1)
  38         self.im = None  # Magick image
  39 
  40         ## Construct "File" menu
  41         self.menuBar = wx.wxMenuBar()
  42         self.menuFile = wx.wxMenu()
  43         self.menuFile.Append(ID_FILE_OPEN, "&Open image","")
  44         wx.EVT_MENU(self, ID_FILE_OPEN, self.OnOpen)
  45         self.menuFile.AppendSeparator()
  46         self.menuFile.Append(ID_FILE_EXIT, "E&xit", "")
  47         wx.EVT_MENU(self, ID_FILE_EXIT,  self.OnExit)
  48         self.menuBar.Append(self.menuFile, "&File");
  49 
  50         ## Construct "Process" menu
  51         self.menuProcess = wx.wxMenu()
  52         self.menuProcess.Append(ID_THRESHOLD, "Threshold", "")
  53         wx.EVT_MENU(self, ID_THRESHOLD,  self.OnThreshold)
  54 
  55         self.menuBar.Append(self.menuProcess, "&Process")
  56         self.SetMenuBar(self.menuBar)
  57 
  58     def OnOpen(self, event):
  59         fd = wx.wxFileDialog(self, "Open Image", "", "", "*.*", wx.wxOPEN)
  60 
  61         if fd.ShowModal() == wx.wxID_OK:
  62             self.loadImage(fd.GetPath())
  63         fd.Destroy()
  64 
  65     def loadImage(self, path):
  66         try:
  67             self.im = PythonMagick.Image(path)
  68             self.iPanel.display(self.im)
  69         except IOError:
  70             print "can't open the file"
  71 
  72     ##-------------- Process ------------------------
  73 
  74     def OnThreshold(self, event):
  75         self.im = self.Threshold(self.im, 0.5)
  76         self.iPanel.display(self.im)
  77         #self.im.write('d:/threshold.tif')
  78 
  79     def Threshold(self, image, threshold):
  80         """
  81         Threshold image. Input threshold is normalized (0-1.0)
  82         """
  83         img = PythonMagick.Image(image) # copy
  84         img.threshold(threshold *65535.0)
  85         return img
  86 
  87     ##-----------------------------------------------
  88 
  89     def OnCloseWindow(self, event):
  90         self.Destroy()
  91 
  92     def OnExit(self, event):
  93         self.Close(True)
  94 
  95 #---------------------------------------------------------------------------
  96 
  97 class mtApp(wx.wxApp):
  98     def OnInit(self):
  99         frame = mtFrame(wx.NULL, -1, "MagickSimple1")
 100         frame.Show(True)
 101         self.SetTopWindow(frame)
 102         return True
 103 
 104 app = mtApp(0)
 105 app.MainLoop()

-Bob Klimek 9-23-03

Thanks

Another word of thanks. I used the pil->image with alpha tricks learned from this page.

Anyone know whether there are newer techniques, or is this std? The page was updated 2003 (I think I recall.) (Get hold of me on the fonty python mailing list on google groups.) \d

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.