In the realm of product design and user interaction, the significance of visual communication cannot be overstated. In today's fast-paced world, the ability to captivate and engage customers within seconds is paramount. This is where Qt dynamic image loading and static image rendering become critical capabilities in embedded product displays. Qt for embedded systems provides a comprehensive framework for both static and on-the-fly Qt dynamic image loading, serving as the foundation for embedded GUI development with Qt and TouchGFX in resource-constrained environments. Leveraging digital transformation services in embedded UI design helps teams adopt these advanced Qt dynamic image loading techniques more efficiently.
Image handling in Qt for Embedded Systems
At the heart of embedded product displays lies the visual allure of images. Qt for embedded systems is a capable library that can be used to render a variety of images — making it one of the leading embedded graphics libraries for MCU-based products. The Qt dynamic image loading capabilities of Qt for embedded systems allow designers to build responsive, visually rich UIs even on microcontrollers with limited RAM. Qt is also part of the broader landscape of embedded graphics libraries including TouchGFX, LittlevGL, and LVGL. For teams pursuing embedded GUI development with Qt and TouchGFX, Qt for MCU provides the most mature tooling and simulator support.
The below picture shows how Qt for embedded systems handles images.
Image Loading in Qt based Embedded Systems
Based on the application design, Qt for embedded systems will fetch a static image from external flash or use Qt dynamic image loading from external memory to render the picture in the UI. Let us understand these dynamic image loading and static image loading techniques in detail in the upcoming sections. Edge video analytics applications often rely on Qt dynamic image loading to render camera frames in real time on embedded displays.
Image usage in embedded systems GUIs
In embedded systems, images or pictures are used for various purposes depending on the specific application requirements. Here are some common types of image/picture usage in embedded systems:
| Types | Use cases |
|---|---|
| User Interface (UI) Elements | Embedded systems often incorporate graphical user interfaces (GUIs) for user interaction. Images are used to represent buttons, icons, menus, and other visual elements to provide a more intuitive user experience |
| Data Visualization | Images are used to display data in a graphical format, such as charts, graphs, and plots. This is particularly common in embedded systems used for monitoring and control applications where visualizing data trends is important |
| Diagnostic and Debugging Tools | Images can be used in diagnostic and debugging tools to visualize system states, error conditions, sensor readings, or other relevant information for troubleshooting purposes |
| Logo and Branding | Embedded systems deployed in commercial products often display logos or branding images during startup or as part of the user interface to reinforce brand identity |
| Documentation and Help Screens | Images are used in embedded systems to provide visual aids in documentation, user manuals, help screens, and tutorials to assist users in understanding system operation and features |
| Displaying Images or Video Content | Some embedded systems, especially those used in consumer electronics or digital signage, display images or video content for entertainment, advertising, or informational purposes |
These use cases can be achieved using static and dynamic techniques. Static techniques mean pictures that are loaded and presented to the UI will not change, for example, company logo. With dynamic techniques images are loaded or updated in runtime, such as an alarm icon shown based on current error condition. Again, dynamic technique can involve preloaded images or on the fly rendering.
Below are some of the ways for above use cases can be achieved.
| Types | Technique | Approach |
|---|---|---|
| User Interface (UI) Elements | Static | Load the required images as fixed during compile time and display in UI |
| Data Visualization | Dynamic with on-the-fly-loading | Show the dynamically generated images in run time on the UI |
| Diagnostic and Debugging Tools | Dynamic with preloaded images | Show different images available on compile time on the same location of UI |
| Logo and Branding | Static | Load the required images as fixed during compile time and display in UI |
| Documentation and Help Screens | Static | Load the required images as fixed during compile time and display in UI |
| Displaying Images or Video Content | Dynamic with on-the-fly-loading | Show the dynamically generated images in run time on the UI |
Static Image Loading in Qt for Embedded Systems
In Qt for embedded systems, we can define the layout and image component by loading them during compile time. This is the simplest form — no Qt dynamic image loading is needed when images are fixed (for example, company logos or static UI icons). Qt for embedded systems handles static image loading very efficiently, as the images are baked into the firmware flash image.
Image {
width: 130; height: 100
source: 'qrc:/embienlogo.png'
}
Respective Image shall be loaded in the project and included in qmlproject or CMakefile like below.
In the QML project file by using image files property, required images has to be added to the project.
ImageFiles {
files: ['embienlogo.png']
}
In case of a CMakefile project, below approach need to be followed to add image in the project.
qul_add_resource(PROJECT NAME FILES embienlogo.png)
Qt Dynamic Image Loading with Preloaded Images
In some cases, there is a placeholder where one or more images need to be loaded in the same place based on the system state. This is the first form of Qt dynamic image loading — where images are compiled into the firmware but swapped at runtime. Qt for embedded systems handles this efficiently with Qt Object property variables.
For an example, in a cluster , there is a placeholder for headlight where either an icon for Hi-beam state or Low-beam/Dipped state will have to be shown based on the light setting. In the Qt qml, we can define the layout and update image component properties in run time dynamically using a Qt Object property variable. Let us see that with an example below.
In the QML project file by using image files property, Low-Beam and Hi-Beam images shall be added to the project.
Example(Test.qmlproject)ImageFiles {
files: ['embienlogo.png',
'Hi-Beam.png',
'Low-Beam.png']
}
Create a Qt object variable to store the image name as string including path.
Example(TestModel.qml)
pragma Singleton
import QtQuick 2.15
QtObject {
id: TestModel
property string Headlight: '' => Qt Object Variable
}
In the Test.QML, image component source properties can be updated with Qt object variable that holds the image name.
Example(Test.qml)
Image {
Id:Headlight
source: 'qrc:/' + Headlight
}
Now by updating Qt object variable in run time as per need, we can swap the Hi-Beam image and Low-Beam image.
In the below example, we are checking the stored CAN data and updating the Qt object variable to update the Telltale image in the GUI dynamically.
Example(Test.cpp)
void Headlight_Handler ()
{
::TestModel &model = < Model URI >:: TestModel::instance(); => Fetch instance of a singleton qtobject class
if (CAN message indicates Headlight DIM on)
Model.Headlight.setValue(“Low-Beam.png”);
else if (CAN message indicates Headlight Bright ON)
Model.Headlight.setValue(“Hi-Beam.png”);
else /*Headlight OFF*/
Model.Headlight.setValue(“”);
}
Dynamic Loading of Preloaded Images
Qt Dynamic Image Loading with On-the-Fly Rendering
For more user-friendly and engaging product designs, images must be loaded or rendered dynamically at runtime. This advanced Qt dynamic image loading approach allows images received from a mobile phone, cloud, or camera to be displayed in the UI at runtime. It can also render images based on the currently selected theme. This form of dynamic image loading cannot be achieved with the earlier two approaches, as the image is not available in the system during compilation. Qt for embedded systems provides the Qul::ImageProvider and Qul::Image APIs specifically for this form of Qt dynamic image loading.
The process involved in achieving this in Qt is as follows.
- Fetch a custom or user image to the embedded system/product via wired or wireless interface.
- Decode the image and convert it to one of the image formats supported in Qt as listed below.
- PixelFormat_ARGB32
- PixelFormat_RGB32
- PixelFormat_RGB888
- PixelFormat_RGB16
- PixelFormat_Alpha8
- PixelFormat_Alpha1
- PixelFormat_ARGB4444
- PixelFormat_RGB332
- PixelFormat_RLE_ARGB32
- PixelFormat_RLE_RGB32
- PixelFormat_RLE_RGB888
- Develop a CPP class for image components and map the same to the image via
source: 'image://Image Container/' - Image Container class shall implement the requestImage method to draw the image on GUI pixel by pixel
One big change from earlier discussed 2 approach is that when developers compile the code, they don't have the actual image they need to display on the UI. Instead, the developer just set aside a space for the image. Developers will fill in this space later when they get the image information. Let's say a driver connects their phone to their car using Bluetooth or Wi-Fi. When the driver gets a call, the car's screen should show the caller's phone number and picture to make it more engaging.
Assume call info and picture are received in the board and now, let's figure out how to make the picture show up on the car's UI screen for the driver.
Step 1:Create a Qt object variable to enable or disable the visibility of image.
Example(TestModel.qml)
pragma Singleton
import QtQuick 2.15
QtObject {
id: TestModel
property bool CallerNotificationvisble: false => Qt Object Variable
}
Create an image component in QML and provide the source of the image as CallerNotification.
CallerNotification class should be equipped with methods to process the Qt request to draw image in UI.
This can be achieved in Qt using Qul::ImageProvider and Qul::Image to display an image at run time.
Image {
source: 'image://callernotification/' + 'profile.png'
width: 800
height: 480
visible: TestModel.CallerNotificaitonvisible
}
Create callernotification class to implement Qt draw requests for image component. In the request image method, allocate a memory for image component and fill the memory with received user profile picture data.
CallerNotification.h:
#include
#include
#include
#include
#include
#include
struct MyImageLoadedEvent
{
MyImageLoadedEvent(Qul::Image &image)
: sharedImage(image)
{}
Qul::SharedImage sharedImage;
};
struct CallerNotification : public Qul::ImageProvider, public Qul::EventQueue
{
Qul::SharedImage requestImage(const char *imageName, size_t imageNameLength) QUL_DECL_OVERRIDE;
void onEvent(MyImageLoadedEvent *const &event) QUL_DECL_OVERRIDE;
void onEventDiscarded(MyImageLoadedEvent *const &event) QUL_DECL_OVERRIDE;
private:
Qul::SharedImage sharedImage;
};
#include 'callernotification.h'
#include
#include
Qul::SharedImage CallerNotification::requestImage(const char *imageName, size_t imageNameLength)
{
// Create the image and mark it as being-written-to
Qul::Image img(800, 480, Qul::PixelFormat_RGB16);
sharedImage = img;
img.beginWrite();
// Start the image loading process.
//
// When done, post an event to trigger endWrite().
// (postEvent() is safe to call asynchronously, while endWrite() is not)
// Fill a segment of the image with a solid color
assert(this->sharedImage.image());
Qul::Image &image = *(this->sharedImage).image();
uint16_t *pixelBegin = reinterpret_cast(
image.bits() + image.bytesPerLine() * image.height());
uint16_t *pixelEnd = reinterpret_cast(
image.bits() + image.bytesPerLine() * image.height());
memcpy(pixelBegin, , size);
}
void CallerNotification::onEvent(MyImageLoadedEvent *const &event)
{
// Causes the finished image to become visible.
event->sharedImage.image()->endWrite();
Qul::PlatformInterface::qul_delete(event);
}
void CallerNotification::onEventDiscarded(MyImageLoadedEvent *const &event)
{
// Causes the finished image to become visible.
event->sharedImage.image()->endWrite();
Qul::PlatformInterface::qul_delete(event);
}
Register CallerNotification class with the application and attach with Qt application using addImageProvider API.
int main()
{
Qul::initHardware();
CallerNotification mycallerProvider;
Qul::Application app;
app.addImageProvider('CallerNotification', &mycallerProvider);
With the above approach we have completed including handling of custom image in Qt for MCU. Now to complete the flow, once the call information received in cluster at predefined memory location, enable the image component visibility true to draw the profile picture received in caller information.
Step 5: Example(Test.cpp)
void Notification_Handler ()
{
Model URI::TestModel &model = Model URI :: TestModel::instance(); => Fetch instance of a singleton qtobject class
If (Call Notification available){
/*Decode the image and store in SDRAM*/
Model.CallerNotificationvisble.setValue(true);
}
}
With the above step showing of user profile picture in product can be successfully achieved.
Dynamic Loading of On-the-fly Images
Conclusion
In the landscape of embedded systems, image usage spans from static branding elements to dynamically updating visualizations. By understanding the nuances of Qt dynamic image loading methodologies — preloaded swapping and on-the-fly rendering — developers using Qt for embedded systems can tailor solutions to meet diverse application needs efficiently. These dynamic image loading techniques form the building blocks of advanced embedded GUI development with Qt and TouchGFX for automotive clusters, medical devices, and industrial HMIs. Qt for embedded systems, as one of the leading embedded graphics libraries, continues to evolve with better tooling and simulation support to accelerate development cycles.
Embien has been in the field of Qt for embedded systems designs for many years, helping customers realize stunning GUIs on resource-constrained embedded systems. Get in touch with our Qt development team to leverage our Qt dynamic image loading expertise.
