Development/Architecture/KDE3/Imaging and Animation
KDE Image I/O library kimgio
Reading and writing images
This library allows applications that use the Qt library to read and write images in extra formats. Current formats include:
|JPEG||X||if QImgio/libjpeg is installed|
if JasPer is installed
|PNM (several variants) (Qt)||X||X|
|PBM (several variants) (Qt)||X||X|
|GIF* (87 & 89a) (Qt)||X||X|
- Due to patent reasons, GIF support isn't compiled in Qt by default. You need to enable it with ./configure -gif when compiling Qt.
Note that this is only legal if you've got a license from Unisys or don't live in a country where Unisys holds a patent on the LZW compression. Countries in that Unisys holds a patent include Canada, Japan, the USA, France, Germany, Italy and the UK. There is more information about that topic on the Unisys web site.
To use these formats, you must
- link the application with the libkimgio library
- Include the #include <kimgio.h> header file.
- call kimgioRegister() once, somewhere in your code before you load an image.
Please read the documentation for the QImageIO class in the Qt documentation.
- When writing handlers, there is a function naming convention; suppose, for example, we were writing PNG read and write handlers, we would name them
void kimgio_png_read ( QImageIO * ); void kimgio_png_write( QImageIO * ); i.e. kimgio_<format>_<read/write>
This should reduce the chance of identifier clashes with other code.
- If you only have either a reader or the writer for a particular format, don't use NULL in QImageIO::defineIOHandler. Instead, write a stub function for the unimplemented handler which displays a message on standard output. This prevents kimgio-using programs dumping core when attempting to call the unimplemented handler.
Qt's QImage class provides a hardware independent image representation class for the programmer. It can load and save files and allows - contrary to a QPixmap - direct access to the image data. This is useful for direct pixel based image manipulation.
The QImage class has already some useful builtin functions like color depth conversion, smooth scaling, mirroring an image, painting text strings into it and also some other stuff. Be sure to read the QImage documentation for more details.
There are slow functions to convert between a QPixmap and QImage. They should be avoided especially for large images if possible. They're slow because the image data might need to be converted in depth and byte order and need to be transferred over a possibly slow network connection to the X server.
Qt's QMovie class provides incrementally loading an image or an image animation, signalling as it progresses.
A QMovie provides a QPixmap as the framePixmap(), and connections can be made via connectResize() and connectUpdate() to receive notification of size and pixmap changes. All decoding is driven by the normal event processing mechanisms, so make sure that you regularly return to the X11 event loop to make the animation not look ugly. The simplest way to display a QMovie, is to use a QLabel and QLabel::setMovie().
The movie begins playing as soon as the QMovie is created (actually, once control returns to the event loop). When the last frame in the movie has been played, it may loop back to the start if such looping is defined in the input source.
QMovie objects are explicitly shared. This means that a QMovie copied from another QMovie will be displaying the same frame at all times. If one shared movie pauses, all pause. To make independent movies, they must be constructed separately.
The set of data formats supported by QMovie is determined by the decoder factories which have been installed, and the format of the input is determined as the input is decoded.
QMovie's animations can be loaded from animated GIF files only if the gif support has been compiled in Qt. See the section about Kimgio above for more information.
QMovie doesn't yet support the MNG format, that is the animated "variant" of PNG. However, Troll Tech has implemented a very nice and far superiour add-on to PNG as an replacement, which is unfortunately not yet standardized. However, they're working on adding it to the PNG standard and we all hope that they will succeed.
The animated, well compressed PNG animation is supported by the yet experimental QPNGImagePacker class. The resulting PNG files are far better compressed than the animated GIF equivalents, because in every frames there is only the "difference" to the previous frame is stored. This is done by using transparency in the parts of the frame that hasn't changed.
It is currently only recommended to use the non-standardized PNG animations if you fully control the creation and loading of these images, i.e. the user doesn't need to manipulate the images with other programs for obvious reasons.
Note that currently the animated PNG files are only supported if Qt was linked statically with it's own distributed libpng. This is done by default. It will not work with the standard libpng that may be part of your system, as it uses a non-standardized extension.
KPixmap inherits QPixmap, so it can be used as a compatible drop-in replacement for QPixmap. It has become a little bit obsolete in my opinion, but it still provides some nice features over QPixmap.
KPixmap provides an easier and probably a little bit faster dithering management and conversion code. It has two new color modes, WebColor and LowColor, applicable to 8bpp displays.
In WebColor mode all images are dithered to the Netscape palette, even when they have their own color table. WebColor is the default mode for KPixmap so that standard applications can share the Netscape palette across the desktop.
In LowColor mode images are checked to see if their color table matches the KDE icon palette. If the color tables do not match, the images are dithered to a minimal 3x3x3 color cube. LowColor mode can be used to load icons, background images etc. so that components of the desktop which are always present use no more than 40 colors.
It can also check if the color table of an image matches the Icon (KPixmap) palette or not. An image with one color not found in the Icon palette is considered to make a match, since this extra color may be a transparent background.
KSharedPixmap is a very cool new class that is now used in KDE's core applications. It enables sharing of pixmaps between different programs. This is currently used to share the pixmap that is set by kdesktop, the desktop management and wallpaper painting program of KDE, between kdesktop and konsole which might use it to implement the pseudo transparency feature.
A shared pixmap is a pixmap that resides only once in the X server. Every shared pixmap is referenced by an ID string, which has to be globally unique (unique among all X clients).
You make a pixmap accessible to other X client by publishing it, using publish().
Normally, if an X client exits, all its resources (including pixmaps) are deleted. This might give undesireable effects when other clients are using that pixmap. If you want to keep the pixmaps around, use setKeepResources(). This will keep _all_ this client's X recources in the server until it resets so don't use without thought.
KSharedPixmap inherits of course KPixmap, so it can be used wherever a KPixmap or a QPixmap can be used.
Did you ever see breathtaking gradient effects i.e. in popup menues of other window managers? Now you don't need to miss them any longer with KDE! KDE developers have implemented a wide variety of QPixmap based effects. As they're based on QPixmaps, they're normally hardware-accelerated by your graphics card and therefore bleeding fast.
KPixmapEffects supports a wide variety of gradient effects including
both in a "balanced" and in a "unbalanced" variant. As an image helps more than thousand words, you'll see some samples of them here:
Additional effects include changing the intensity of pixmaps, providing blend effects, creating pattered "images", or "flattening" as well as fading. Be sure you don't miss them!