Repository navigation
Home
A QGIS plugin that shows pictures attached to ArcGIS Feature Service layers, and puts them into print layouts and atlas.
All traffic goes through the QGIS authentication manager, so services secured with OAuth2 on an ArcGIS Enterprise portal work without handling tokens by hand. Attachments on the layer itself and on related tables are found automatically.
Contents
- Requirements
- Installation
- Quick start
- The picture panel
- Pictures in a print layout
- Expression functions
- Troubleshooting
- Limitations
- Reporting issues and contributing
- License
- QGIS 3.40 or newer, including QGIS 4.
- A layer loaded from an ArcGIS Feature Service (the ArcGIS REST Server data source), with attachments enabled on the layer or on a related table.
- No additional Python packages.
From the QGIS plugin repository
- Plugins → Manage and Install Plugins → All.
- Search for Esri Picture Function and click Install Plugin.
From a zip file
- Download the zip from the releases page.
- Plugins → Manage and Install Plugins → Install from ZIP.
After installation the plugin adds a toolbar with two buttons: the picture panel and Copy HTML template.
- Add the ArcGIS Feature Service layer to the project. For a secured service, pick its authentication configuration when you add the layer.
- Make the layer active in the layer tree and open the panel from the toolbar.
- Select one or more features on the map. Their pictures appear in the panel, and the features are marked green on the map.
- Click a picture to see which feature it belongs to. Double-click to open it in your default image viewer.
The panel shows the pictures of the selected features in the active layer. If the attachments sit on a related table rather than on the layer itself, the table is found automatically. When there are several, pick one in the drop-down at the top of the panel.
Pictures are always listed under the object id of the feature on the map, also when they actually hang on a related record. The tooltip of a picture shows both.
Keep is on by default. While it is ticked:
- deselecting features does not empty the panel,
- new selections are added to what is already shown,
- the panel stays with its layer, even if you click another layer in the layer tree.
Untick Keep to make the panel follow the current selection only. Clear panel removes every picture and starts over.
Pictures are fetched in batches of 25 features. The first batch starts by itself. When more features are waiting, a bar shows how far the fetch has come, for example 50 of 140 feature(s) fetched, 90 waiting:
| Button | Does |
|---|---|
| Next 25 | Fetches the next batch |
| All | Fetches every waiting feature, one batch after the other. Asks first when more than 100 features are waiting |
| Stop | Stops the fetch. Features not yet fetched stay waiting |
With Mark on map ticked:
| Colour | Means |
|---|---|
| Green | The feature's pictures are in the panel |
| Grey | The feature was fetched but has no pictures |
| Yellow | The feature of the picture you clicked |
The marks disappear while the panel is hidden.
Clicking a picture flashes its feature on the map. Right-click a picture for:
| Menu item | Does |
|---|---|
| Open picture | Opens it in your default image viewer |
| Zoom to feature | Zooms to the feature (pans, for point layers) |
| Select feature | Selects the feature without changing the panel |
| Show attribute form | Opens the feature's form |
| Save as… | Saves the original file |
| Rotate thumbnail | Turns the thumbnail 90° in the panel |
Thumbnails are not rotated by their EXIF tag, because that would slow down loading considerably. Pictures exported for a layout are rotated.
Pictures are cached on disk in esri_attachments under the system's temp
folder. At start-up, files older than 14 days are removed, then the oldest
files until the cache is below 500 MB. Clear cache empties it at once and
shows how much space it uses.
If inspecting the service fails, for example because a login has expired, a Try again button appears. If the service itself has changed while the project is open (attachments or a relationship added), reopen the project.
Neither the picture item nor the HTML item in a layout can fetch pictures from a secured service. The pictures are therefore exported to a folder first, with predictable file names, and the layout reads them from there.
- Get the features you need into the panel.
- Click Export for layout in the panel. Every feature in the panel is exported, also those still waiting to be fetched.
- Choose a folder. Use a path without spaces or non-ASCII characters
(æ, ø, å) —
file:///links in the HTML item are fussy about both.
The export rotates every picture by its EXIF tag and caps it at 1600 pixels on the long edge. The layout renderer ignores EXIF rotation, and full-size originals make the exported PDF very large for no visible gain.
The export folder is stored in the project file. Save the project after exporting, or the layout finds no pictures the next time it is opened.
Create a layout, enable Atlas, and choose the layer as coverage layer. Then pick one of the two options below.
Simple, and works in every QGIS version, but with a fixed number of pictures.
-
Add a picture item.
-
Data-define Image source with:
esri_picture("OBJECTID", 1) -
Set Resize mode to Zoom.
-
Copy the item and change
1to2,3… for more pictures.
Features with fewer pictures leave empty frames.
Shows all pictures of the atlas feature in one column, as wide as the frame, and continues on new pages when needed.
- Add an HTML item.
- Click Copy HTML template in the toolbar, and paste it into the item's Source.
- Set the item properties:
| Setting | Value |
|---|---|
| Evaluate QGIS expressions in HTML source | Ticked |
| Frames → Resize mode | Extend to next page |
| Use smart page breaks | Ticked |
| Maximum distance | At least the height of the tallest picture plus the gap — 180 mm with the template's defaults |
If your layer's object id field is not called OBJECTID, change it in the
template.
Picture size. The pictures follow the frame width automatically.
Portrait pictures are capped by max-height in the template (170 mm by
default). Keep max-height below the frame height.
Why Maximum distance matters. A smart page break looks upwards from the bottom of the frame for an empty row of pixels, but no further than Maximum distance. With the default 10 mm it rarely reaches the gap above a picture, and the picture is cut in half across the page break.
Several frames. With Extend to next page the item renders at the width of its widest frame. Keep the frames the same width.
Both functions are in the Esri Pictures group in the expression builder.
| Function | Returns |
|---|---|
esri_picture(oid, n) |
Path to the n'th exported picture of the feature, or an empty string |
esri_pictures(oid) |
Array of paths to every exported picture of the feature |
Paths use forward slashes and can go straight into a file:/// link.
Example, a list of pictures in an HTML item:
[% array_to_string(
array_foreach(
esri_pictures(attribute(@atlas_feature, 'OBJECTID')),
'<img src="file:///' || @element || '">'
), '') %]
The layout shows no pictures. Save the project after the export — the folder is stored in the project file. Check that the folder path has no spaces or non-ASCII characters, and that the object id field name in the expression matches the layer.
A picture is cut in half at the page break. Raise Maximum distance under Use smart page breaks to at least the height of the tallest picture. See Option B.
Pictures on narrower pages are clipped. The HTML item renders at the width of its widest frame. Make all frames the same width.
Only some features were fetched. Large selections are fetched 25 at a time. Use Next 25 or All in the bar above the pictures.
Error: 498 / 499, or "Invalid token". The login has expired. Log in again through the layer's authentication configuration and click Try again.
A thumbnail is upside down or sideways. Thumbnails are not EXIF-rotated. Right-click → Rotate thumbnail. The picture is exported the right way round.
The panel says the layer is not an ArcGIS Feature Service layer. The plugin works only with layers loaded through the ArcGIS REST Server data source, not with WMS, WFS or local copies.
The HTML item is blank in QGIS 4. The HTML item relies on a web engine that differs between QGIS 3 and QGIS 4. Use Option A, or report the issue with your QGIS version.
More details are in the QGIS message log, under the Esri Pictures tab (View → Panels → Log Messages).
- Attachments are found one relationship step from the layer. Deeper structures are not discovered.
- Exported file names are
<OBJECTID>_<n>.<ext>and carry only the feature's object id, not the attributes of a related record such as date or surveyor. - The export takes at most three pictures per feature.
Report bugs and suggestions in the issue tracker. Please include:
- your QGIS version and operating system,
- whether the attachments are on the layer or on a related table,
- the messages from the Esri Pictures tab in the log panel.
Do not paste service URLs, tokens or authentication ids from internal services into public issues.
Pull requests are welcome. The code is plain PyQGIS and must run on both
QGIS 3.40 and QGIS 4 — use fully qualified enums such as
Qt.ItemDataRole.UserRole.
Copyright © 2026 Klaus Agerskov. Released under the GNU General Public License, version 3. See LICENSE.