Differences between revisions 29 and 30
Revision 29 as of 2001-06-09 04:28:52
Size: 6207
Editor: anonymous
Comment: missing edit-log entry for this revision
Revision 30 as of 2001-06-09 04:30:26
Size: 6178
Editor: anonymous
Comment: missing edit-log entry for this revision
Deletions are marked like this. Additions are marked like this.
Line 9: Line 9:
in memory manipulation (and particular generation) of images for use in-memory manipulation (and particularly the generation) of images for use
Line 44: Line 44:
== Dynamic Bitmaps ==

=
== PIL (Python Imaging Library) ===
== PIL (Python Imaging Library) ==
Line 59: Line 57:
=== Numeric Python === == Numeric Python ==
Line 72: Line 70:
==== Slicing ==== === Slicing ===
Line 87: Line 85:
==== Examples ==== === Examples ===
Line 117: Line 115:
=== Screen Capture === == Screen Capture ==

Working with Images

Images and bitmaps in wxPython are normally created by loading files from disk. Working with the images in memory is, however, a common task for certain types of application. This recipe set looks at the in-memory manipulation (and particularly the generation) of images for use in wxPython applications.

Table of Contents: TableOfContents

Formats and Conversions

  • Conversions among wxImage, wxBitmap, wxCursor, wxIcon and DATA
    • wxImage to wxBitmap --  myWxImage.ConvertToBitmap() or wxBitmapFromImage(myWxImage) 

      wxImage to DATA --  myWxImage.GetData()  returning a string in width * height * 3 format

      DATA to wxImage --  image = wxImage(); image.SetData( data )  where data is a Python string of length width * height * 3. DATA to wxBitmap -- Go through wxImage to get to wxBitmap. DATA to wxIcon -- Should be possible, but I don't see an overloaded-constructor name for it.

      wxIcon to wxBitmap --  bitmap = wxEmptyBitmap( icon.GetWidth(), icon.GetHeight()); bitmap.CopyFromIcon( icon ) 

    There seem to be some missing functions, not sure if these are available at a lower level of abstraction for the C peoples, but anyway, here's what hopefully will show up some day:
    • wxBitmap to DATA or wxImage -- Probably the most critical missing item, currently you have to use "save to file" then load the bitmap back from disk using a wxImage. DATA or wxImage to wxCursor -- Should be an overridden constructor available, not yet. wxIcon to DATA or wxImage -- To allow for editing of icons, this would be required. wxCursor to 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.

PIL (Python Imaging Library)

  • PIL can be used with wxPython if image processing services are required beyond loading the formats built into wxPython. DATA formatted strings can be created from PIL Image objects using the .convert and .tostring methods (as show in the example below). Note the use of the size attribute of the PIL Image to create the empty wxImage object.

        def GetBitmap( self ):
                import Image
                source = Image.open( r"Z:\mcfport\portfoli\full\claire.jpg", 'r')
                image = apply( wxEmptyImage, source.size )
                image.SetData( source.convert( "RGB").tostring() )
                return image.ConvertToBitmap() # wxBitmapFromImage(image)

Numeric Python

  • This example shows the creation of a bitmap using a Numeric Python array as the data source. Note that Numeric uses reversed column-row ordering compared to wxPython, so you'll need to make sure that you generate images using height, width, not width, height coordinates. Also note the use of the 'c' data type for image data in rgb format.

        def GetBitmap( self, width=32, height=32, colour = (0,0,0) ):
                array = Numeric.zeros( (height, width, 3),'c')
                array[:,:,] = colour
                image = wxEmptyImage(width,height)
                image.SetData( array.tostring())
                return image.ConvertToBitmap()# wxBitmapFromImage(image)

Slicing

  • Numeric'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 Numeric'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).

        def GetBitmap( self, width=32, height=32, colour = (128,128,128), border=5, borderColour=(255,255,255) ):
                # creates a bitmap with a border
                array = Numeric.zeros( (height, width, 3),'c')
                array[border:-border,border:-border,:] = colour
                array[:border,:,:] = borderColour
                array[-border:,:,:] = borderColour
                array[:,:border,:] = borderColour
                array[:,-border:,:] = borderColour
                image = wxEmptyImage(width,height)
                image.SetData( array.tostring())
                return image.ConvertToBitmap()# wxBitmapFromImage(image)
  • This example creates a 256-level red gradiant. Note that real-world programs creating gradiants are likely to use 'd' type with 0.0 to 255.0 values to allow for processing the gradiant without integer semantics making things hard, then doing  array.astype( 'c')  before converting to a string.

        def GetBitmap( self ):
                ## Create a 256-level gradiant
                array = Numeric.zeros( (height, width, 3),'c')
                array[:,:,0] = range( 256 )
                image = wxEmptyImage(width,height)
                image.SetData( array.tostring())
                return image.ConvertToBitmap()# wxBitmapFromImage(image)

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 that this only captures the client area, I haven't been able to figure out how to capture the entire window.

        def OnToFile( self, event ):
                context = wxPaintDC( self )
                memory = wxMemoryDC( )
                x,y = self.GetClientSizeTuple()
                bitmap = wxEmptyBitmap( x,y, -1 )
                memory.SelectObject( bitmap )
                memory.Blit( 0,0,x,y, context, 0,0)
                memory.SelectObject( wxNullBitmap)
                bitmap.SaveFile( "test.bmp", wxBITMAP_TYPE_BMP )

WorkingWithImages (last edited 2011-06-20 15:32:02 by pool-71-244-98-82)

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