A CODESYS image element cannot take its path from a string variable at runtime. Switch between registered pool entries with a Bitmap ID variable, or copy the selected file over one fixed image and increment the Bitmap version integer. An external control is the last resort for arbitrary path strings.
The standard CODESYS image element cannot be pointed at a new file while the controller runs. The element holds one image reference, fixed when you build the visualization, and the mechanism for change is an integer. When the integer linked to the Bitmap version property changes, the visualization re-reads the file behind the Image ID property. Every dynamic image job lands in one of three designs: switch between registered pool entries with a Bitmap ID variable, overwrite one fixed file and bump its version, or put an external control on the screen and hand it the path yourself. This article compares the three and works a 40-image database case through its numbers.
Can the image element take its file path from a string variable?
No. The element has no property that accepts a path string, so the common design of an array of path strings, one string linked to the element, has nowhere to connect. The path is fixed at engineering time, in the element or in the pool.
The runtime side of the element offers three handles. The Image ID property names the image it shows. The Bitmap version property takes an integer that forces a re-read when it changes. On an image pool, the Bitmap ID variable takes a PLC variable that selects the registered entry, PLC_PRG.imagevar in the example printed in the product's own image pool documentation. These sit with the advanced element properties, past the standard list.
None of the three is a path string. That is the whole constraint: the set of paths is decided when you build the project, and runtime code decides which of them is shown, or when the one shown is re-read.
If you are still deciding what to place on the screen in the first place, choosing HMI image and video widgets for a visualization covers the groundwork this article does not repeat.
How does the Bitmap version variable refresh a fixed image?
Link an integer variable to the element's Bitmap version property. When its value changes, the visualization clears the cached copy and reads the file named in the Image ID property again. The path itself never changes.
Your application owns both halves of the job. It writes the new content to the file at that path, then changes the integer. The visualization does no watching of the file on its own: the product help is explicit that the application must be programmed for this. If the file changes and the integer does not, nothing happens on screen.
The help names two uses for the property: graphics the application generates itself, and images refreshed by a camera. Both share the same shape, one fixed path whose content keeps changing. Increment the integer by one after every write, 0, 1, 2, 3, and any change in the value triggers the re-read. For a camera view, refresh a camera still image on an operator display covers the pacing side of that job.
When is an ImagePool the right way to switch images?
When every image the operator could ever need is known while you build the project. Register the images as pool entries once, then switch between them at runtime by writing an entry's ID to the Bitmap ID variable.
Twelve fault icons, five product photos, a row of status symbols: fixed counts, artwork known before commissioning. The pool is the clean answer there. One integer on the PLC side does the switching, there is no file copying and no version bookkeeping.
The constraint is the flip side of the tidiness. Entries are registered at engineering time, so a thirteenth icon that appears after commissioning costs an edit at the engineering tool and a download to the controller. A pool that must grow while the line runs is the wrong mechanism.
How do you show database images whose paths arrive at runtime?
Copy the selected image to one fixed file on the controller, keep the element pointed at that file, and increment the Bitmap version after every copy. That design holds for any number of images, because the visualization only ever knows the one path.
Decide in this order:
- The set is bounded and known at engineering time. Register every image in a pool and switch with the Bitmap ID variable.
- The set changes at runtime, and one image on screen at a time is enough. Point the element at one fixed file. The application reads the path string from the database, copies that file to the fixed path, then increments the version.
- Path strings must be loaded directly, with no copy step available. Put an external control, an ActiveX-style element, on the screen and hand it the path. This is the only one of the three that accepts a path at runtime, and it costs the most integration work.
Step 2 is the answer for the database case in almost every plant. The visualization never learns about the other images, so it never needs to change when the table grows.
If the screen is a web visualization in a browser, there is a fourth road: serve a database image through an HTTP endpoint and let the browser fetch a URL. The path problem disappears because the URL is fixed and the content behind it changes.
Which mechanism fits which job?
The pool for a bounded set, the fixed file with its version integer for anything that changes at runtime, the external control only for arbitrary paths. The table puts the three side by side, and the recommendation below is the decision.
| Mechanism | You change at runtime | Fixed at engineering time | Wins at | The cost |
|---|---|---|---|---|
| ImagePool with Bitmap ID variable | An integer selecting a registered entry | Every image and every path | Bounded sets: fault icons, product photos, symbols | A new image needs an engineering edit and a download |
| One fixed file with Bitmap version | The file content and an integer | One path in the Image ID property | Runtime content: camera frames, generated graphics, database picks | Your application does the copy; one image on screen at a time |
| External control | The path handed to the control | Nothing about the image set | Arbitrary path strings, sets that can never be enumerated | The most integration work, plus a platform dependency |
Where each wins: the pool wins on a fixed, modest set you can enumerate at a desk. The fixed file with its version integer wins on content that arrives while the controller runs. The external control wins only where paths must be consumed as strings.
Recommendation: Register the images in an ImagePool when the whole set exists at engineering time. When the images arrive or change while the controller runs, copy the selected one over a single fixed file and increment the Bitmap version after each copy. Take the external-control route only when path strings must be loaded directly and no copy step can be arranged.
How does a 40-image changeover scenario work out?
Take 40 label artworks in a database table, one changeover every 20 minutes, and one operator screen on the line. The fixed-file design needs one path, one integer variable and 24 copies per shift: 8 x 60 / 20 = 24.
Set it up like this:
- The database table holds 40 rows, each with a path to one artwork file.
- The element's Image ID property names one fixed path on the controller,
/visu/current.png. - On each changeover the application reads the selected row, copies that artwork to
/visu/current.png, then runsversion := version + 1.
The arithmetic over one 8-hour shift: 8 x 60 = 480 minutes, 480 / 20 = 24 changeovers, so 24 copies and 24 increments. After one full cycle through all 40 recipes the version integer reads 40, and the visualization has been rebuilt zero times.
Now add recipe 41 in the database. The fixed-file design absorbs it with no engineering work: row 41 is another file copied to the same path. The pool design for the same job needs 41 registered entries, and entry 41 arrives as an edit and a download after the line is running.
Two habits keep it clean. Keep every replacement the same pixel size as the original, so the element's position and scaling hold. Write the file completely before incrementing the version. When the artwork reaches the controller over the network, display FTP images in an industrial dashboard covers the delivery half of that job.
What makes the screen show a stale image at runtime?
The version integer not changing. The visualization re-reads the file only when the linked integer changes, so a file written without the increment leaves the operator looking at the previous image. Write the file completely, then increment.
Treat the write and the increment as one operation, in that order. Increment before the copy finishes and the re-read can pick up the previous content. Test the design by writing two different artworks to the fixed path and bumping the integer between them: the screen should change on the bump, and on nothing else.
Questions
Can I add a new image to the ImagePool while the controller is running?
No. Pool entries are created at engineering time, so an image that appears after commissioning needs an edit at the engineering tool and a download to the controller. That is the working test for the pool: if the set can grow while the line runs, use the fixed-file design with the Bitmap version instead, where a new image is just another file copied to the same path.
Does the Bitmap version variable change which file the element reads?
No. The element keeps reading the file named in its Image ID property. The version integer only signals that the content of that file changed, so the visualization drops its cached copy and reads the same path again. Switching to a different registered image is the job of the Bitmap ID variable on an ImagePool.
Is there a documented limit on how many images an ImagePool can hold?
No maximum is documented in the material cited here. The limit that bites first is effort: every entry is registered by hand at engineering time, and every later addition costs an edit and a download. For a set of a few dozen images this is a one-off task. For a set that changes weekly it is a maintenance burden.
What happens if my application writes the file but forgets the version variable?
The screen keeps showing the previous image. The re-read is triggered by a change in the linked integer, so the write alone has no visible effect. Treat the copy and the increment as one operation in the application: write the new file completely, then add one to the version, and the operator sees the new image on the next cycle.
Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.