Image Types

Pyface’s image model presumes that there are three different types of image objects provided by a toolkit:

Images

The “image” image type is optimized for pixel access and manipulation. For the Qt toolkit this is the QImage class, while for the Wx toolkit it is wx.Image.

Bitmap

The “bitmap” image type is optimized for rendering to the screen. For the Qt toolkit this is the QPixmap class, while for the Wx toolkit it is wx.Bitmap.

Icon

The “icon” image type is really a collection of related images that represent different states of a GUI, such as disabled, selected, activated and so on. For the Qt toolkit this is the QIcon class, while for the Wx toolkit it is wx.Icon.

Additionally, there may be other sources of images, such as images stored in numpy arrays of appropriate shape and dtype, PIL/Pillow images, and images stored in files, both user-supplied and stored as resources with a Python library.

IImage Interface

To handle all of these different notions of an “image”, Pyface has a base interface IImage that exposes methods for creating each toolkit image type from underlying image data. There are corresponding concrete implementations of the interface for Numpy arrays and image resources.

Additionally, there is an Image trait that is designed to accept any IImage as a value, but to also accept the name of a resource or file to load into an image.

ArrayImage

This implementation of IImage wraps an NxMx3 or NxMx4 numpy array of unsigned bytes which it treats as RGB or RGBA image data. When converting to toolkit objects, the data is copied.

ImageResource

An image resource is an image stored as part of a Python package, either as a file or inside a zip file or similar, and so guaranteed to be available for use in an application for GUI components. Pyface provides the ImageResource class and associated resource discovery machinery to support this use-case.

Resources are specified to the ImageResource by filename (adding standard image file extensions if not present in the name). The Pyface resource system searches for files matching the given name in these places:

  • in “images” directories inside the current Python package

  • in “images.zip” files inside the current Python package

  • in directories given as explicit search paths

If an image of a particular size is requested, the system will also look for directories with names of the form images/{width}x{height} and will use any matching image from these preferentially.

The most common way to specify images for use in button icons or complex TraitsUI table and tree data structures is by adding an “images” directory next to the module using the image, for example:

my_package/
    my_module.py
    images/
        my_image.png

The image code like the following in my_module.py will work:

from pyface.api import ImageResource
from pyface.actions.api import Action

img_res = ImageResource("my_image")
action = Action(image="my_image")

When using this approach, remember that image files will need to be added to the package_data in the project configuration or they will not be shipped alongside the code.

image_helpers Module

Since there is a lot of shared functionality between the various implementations of the IImage interface, the pyface.util.image_helpers module provides a number of functions and other objects to perform lower-level tasks, such as converting between toolkit types.

Implementers of new toolkits will likely want to write their own versions of these, and writers of new concrete IImage implementations may want to make use of them to simplify the implementation of the interface.

ImageLibrary

The ImageResource system is built around supplying image files which are local to the place where they are being used. Sometimes, however, you want your images to be available throughout the application. Pyface provides the ImageLibrary to allow for this use case.

The ImageLibrary is a global object that holds a catalog of ImageVolume objects that in turn contain images and associated metadata. Image volumes are either directories or zipfiles containing images and metadata files.

Accessing Images and Image Metadata

If you give an Image an image name which starts with @, then it will interpret the name to be the id of an image in the ImageLibrary of the form @<volume-name>:<image-name>. Alternatively, you can ask the image library directly for an image resource that corresponds to the id via the image_resource() method:

from pyface.image.image import ImageLibrary
from pyface.actions.api import Action

red_ball_image = ImageLibrary.image_resource("@icons:red_ball")
action = Action(image=red_ball_image)

Each image has an ImageInfo metadata object associated with it which can be obtained via the image_info() method. A list of all known image metadata can be obtained from the images trait.

ImageVolume Instances

Image volumes are represented by the ImageVolume class. Image volumes may have multiple aliases in addition to their primary name, and these aliases can be used as part of the id of an image. The volume which stores an image can be found using the find_volume() method. The catalog and aliases attributes are dictionaries that map names to volume objects.

By default the ImageLibrary is initialized with:

  • an "application" volume which is assumed to be in a “library” directory next to the application executable (ie. whatever is in sys.argv[0] which is usually the main module’s path);

  • the std and icons volumes in pyface/image/library

  • any path listed in the TRAITS_IMAGES environment variable which contains a volume.

Additional volumes can be added programatically by calling add_volume() with the path of a zipfile or directory. Alternatively add_path() can be used to add volume by giving a name for the volume and a directory path to use. If no path is provided in either case, the library will look for an images directory next to the current module.

Just as with image libraries, the image_resource() method returns an ImageResource instance for the specified image name. Additionally, the bytes of the actual image file are available through image_data().

Image volumes have a info trait that holds a list of ImageVolumeInfo instances. These hold metadata about groups of images, including copyright and licensing information. The category and keywords traits hold additional information about the volume itself.

Image volumes are designed to reflect the actual contents of the directories or zipfile that they refer to. The update() method clears and reloads the data from disk. The save() method saves any changes made by the user into the data file.

Images stored in image volumes which are zipfiles are extracted to temporary files as needed for actual use.