1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
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
:class:`~pyface.qt.QtGui.QImage` class, while for the Wx toolkit it is
:class:`wx.Image`.
Bitmap
The "bitmap" image type is optimized for rendering
to the screen. For the Qt toolkit this is the
:class:`~pyface.qt.QtGui.QPixmap` class, while for the Wx toolkit it is
:class:`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
:class:`~pyface.qt.QtGui.QIcon` class, while for the Wx toolkit it is
:class:`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.
:class:`~pyface.i_image.IImage` Interface
-----------------------------------------
To handle all of these different notions of an "image", Pyface has a base
interface :class:`~pyface.i_image.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 :class:`~pyface.ui_traits.Image` trait that is
designed to accept any :class:`~pyface.i_image.IImage` as a value, but to
also accept the name of a resource or file to load into an image.
:class:`~pyface.array_image.ArrayImage`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This implementation of :class:`~pyface.i_image.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.
:class:`~pyface.image_resource.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
:class:`~pyface.image_resource.ImageResource` class and associated resource
discovery machinery to support this use-case.
Resources are specified to the :class:`~pyface.image_resource.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:
.. code-block:: python
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.
:mod:`~pyface.util.image_helpers` Module
----------------------------------------
Since there is a lot of shared functionality between the various
implementations of the :class:`~pyface.i_image.IImage` interface, the
:mod:`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 :class:`~pyface.i_image.IImage`
implementations may want to make use of them to simplify the implementation of
the interface.
:class:`~pyface.image.image.ImageLibrary`
-----------------------------------------
The :class:`~pyface.image_resource.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 :class:`~pyface.image.image.ImageLibrary`
to allow for this use case.
The :class:`~pyface.image.image.ImageLibrary` is a global object that
holds a catalog of :class:`~pyface.image.image.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 :class:`~pyface.ui_traits.Image` an image name which
starts with ``@``, then it will interpret the name to be the id of an
image in the :class:`~pyface.image.image.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
:meth:`~pyface.image.image.ImageLibrary.image_resource` method:
.. code-block:: python
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 :class:`~pyface.image.image.ImageInfo` metadata object
associated with it which can be obtained via the
:meth:`~pyface.image.image.ImageLibrary.image_info` method. A list of all
known image metadata can be obtained from the
:attr:`~pyface.image.image.ImageLibrary.images` trait.
:class:`~pyface.image.image.ImageVolume` Instances
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Image volumes are represented by the :class:`~pyface.image.image.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
:meth:`~pyface.image.image.ImageLibrary.find_volume` method. The
:attr:`~pyface.image.image.ImageLibrary.catalog` and
:attr:`~pyface.image.image.ImageLibrary.aliases` attributes are dictionaries
that map names to volume objects.
By default the :class:`~pyface.image.image.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
:meth:`~pyface.image.image.ImageLibrary.add_volume` with the path of a zipfile
or directory. Alternatively :meth:`~pyface.image.image.ImageLibrary.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
:meth:`~pyface.image.image.ImageVolume.image_resource` method returns an
:class:`~pyface.image_resource.ImageResource` instance for the specified image
name. Additionally, the bytes of the actual image file are available through
:meth:`~pyface.image.image.ImageVolume.image_data`.
Image volumes have a :attr:`~pyface.image.image.ImageVolume.info` trait that
holds a list of :class:`~pyface.image.image.ImageVolumeInfo` instances. These
hold metadata about groups of images, including copyright and licensing
information. The :attr:`~pyface.image.image.ImageVolume.category` and
:attr:`~pyface.image.image.ImageVolume.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
:meth:`~pyface.image.image.ImageVolume.update` method clears and reloads the
data from disk. The :meth:`~pyface.image.image.ImageVolume.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.
|