Ever faced a situation where “everything works on your PC” but the client suddenly can’t load PNG/GIF/WEBP — and you get strange bug reports instead of thanks? Or when one careless conversion turns an image into mush, and trying to fix pixels makes code slow and fragile?
This chapter will reveal why professional Qt developers split raster work into two worlds — and how this decision saves hours of debugging, speeds up output, and improves graphics quality. Here you’ll discover where the boundary between accuracy and speed lies, uncover typical format traps, and learn the secret of avoiding “invisible” deployment problems.
We’ll cover 2 key classes (QImage vs QPixmap), several pixel operations (brightness, inversion, scaling, reflection), and a practical case with scanLine() that shows where real performance is born. Plus — format nuances (PNG/JPEG/WEBP/GIF/XPM) and what exactly you shouldn’t forget when deploying via windeployqt/macdeployqt.
If you want to stop “treating symptoms” and start managing images in Qt confidently — this chapter is best not skipped.
This chapter includes ready-to-use code examples.
Chapter Self-Check
What’s the key difference between context-dependent and context-independent representation when working with raster images?Answer
Correct answer: Context-dependent (QPixmap) displays faster as it matches the current video card’s graphics mode and requires no conversions, but individual pixel access is slow. Context-independent (QImage) allows efficient work with each pixel and saving data in formats not supported by the video card.
Why is Format_ARGB32_Premultiplied format preferable when using QImage as a drawing context?Answer
Correct answer: This format is optimized for Qt drawing operations, as color components are already premultiplied by the alpha channel value, speeding up color blending operations during compositing.
Why is the QPixmapCache class needed and in what situations is its use most justified?Answer
Correct answer: QPixmapCache caches frequently used images in memory, avoiding repeated file loads. Especially useful for icons and interface elements displayed multiple times.
Why is the XPM format considered inefficient for disk space but was still popular in the past?Answer
Correct answer: XPM stores images as C source code, which takes more space than binary formats. It was used for the ability to include images directly in program code, but with Qt’s resource system this necessity has disappeared.
When should you choose QImage versus QPixmap for working with raster images?Answer
Correct answer: Use QImage when you need pixel-by-pixel processing, saving/loading files, or working with formats not supported by the video card. QPixmap — for fast screen display without pixel modification.
Why is QImage’s scanLine() method more efficient than direct pixel access via pixel()?Answer
Correct answer: scanLine() returns a direct pointer to a pixel row in memory, allowing sequential processing without repeated method calls, significantly speeding up bulk image operations.
What will happen if you try to use the pixelIndex() method for Format_RGB32 format images?Answer
Correct answer: The pixelIndex() method only works for Format_Indexed8 format where pixels store color palette indices. For other formats including Format_RGB32, you need to use the pixel() method which returns direct RGB values.
Why is it necessary to include image format plugins when delivering Qt applications with graphics support to clients?Answer
Correct answer: Qt uses a plugin system for supporting various graphics formats. Without corresponding DLL/SO files from the imageformats directory, the application won’t be able to load images of certain formats, even if the code is written correctly.
How do you create a transparent, non-standard shaped window in Qt and what problems does this create for the user interface?Answer
Correct answer: Set the Qt::WA_TranslucentBackground attribute and use an image with alpha channel. Main problem — absence of standard window title bar, so you need to implement window dragging yourself through mouse event handling and add a close button.
Why does the brightness() function from the example create an image copy instead of modifying the original?Answer
Correct answer: This follows the principle of input data immutability and allows using one source image to create multiple variants with different brightness without reloading from file.
Why is WEBP format considered universal for web applications?Answer
Correct answer: WEBP supports both lossy compression (like JPEG) and lossless (like PNG), plus transparency and animation (like GIF), while providing better quality-to-size ratio.
What does the check r > 255 ? 255 : r < 0 ? 0 : r mean in the brightness() function and why is it critically important?Answer
Correct answer: This is clamping of color component value to the 0-255 range. Without this, arithmetic operations can cause values to go beyond the allowable range, causing overflow and color distortion.
What’s the difference between QPainter’s drawImage() and drawPixmap() methods in terms of performance?Answer
Correct answer: drawImage() converts QImage to context-dependent format before displaying, which is slower. drawPixmap() displays QPixmap directly as data is already in the needed format, ensuring maximum output speed.
Practical Exercises
Easy Level
Image Viewer with Brightness Filters
Create an application that loads an image from a file and displays it along with two variants: darkened (brightness -50) and lightened (brightness +50). Arrange all three images in one row. Add ability to save edited images to files.
Hints: Use QImage for loading and processing images. Implement brightness adjustment function similar to the chapter example, using scanLine() for efficient pixel access. For display, use QLabel with setPixmap(). To arrange three images, apply QHBoxLayout. QImage::save() method will let you save results.
Medium Level
Image Effects Gallery
Develop an application that applies various effects to a loaded image and displays them in a grid: original, inverted, horizontally flipped, vertically flipped, reduced 2x, enlarged 1.5x. Add ability to cache frequently used images via QPixmapCache. Implement buttons to switch between different source images.
Hints: Use QImage methods flipped(), scaled(), and invertPixels() to create effects. For layout, apply QGridLayout (2×3 or 3×2 grid). Create a function to apply all effects that returns a list of QPixmap. Use QPixmapCache::insert() with unique keys for caching. QFileDialog will help choose image files. Note Qt::KeepAspectRatio parameter when scaling.
Hard Level
Mini Image Editor with Custom Filters
Create a full-featured raster image editor with non-standard transparent window. Implement: loading/saving files of different formats (PNG, JPEG, WEBP, BMP), applying filters (brightness, contrast, saturation, blur), ability to draw on image using QPainter, undo/redo operations, scaling and reflection. Application window should have transparent areas and custom design without standard title bar.
Hints: Use QImage as main format for storage and processing (Format_ARGB32_Premultiplied). Store change stack for undo/redo functionality. For custom window, apply Qt::WA_TranslucentBackground and Qt::FramelessWindowHint, implement dragging via mousePressEvent() and mouseMoveEvent(). Create separate filter class with methods for each effect. For blur, use convolution with kernel. Implement drawing via QPainter on QImage with mouse event handling. QFileDialog::getOpenFileName() and getSaveFileName() will help with file dialogs. Use QToolBar or custom buttons for control interface.
💬 Join the Discussion!
Figured out the differences between QImage and QPixmap? Have questions about image formats or optimizing raster graphics work?
Maybe you found interesting ways to use context-independent representation or created an unusual image processing filter?
Share your experience, ask questions, or help other readers master working with raster images in Qt!