Imaging module
Digital asset management Bundled: Community edition
The Imaging module simplifies working with images. You don’t need to resize and crop each image by hand as the imaging engine generate variations on the fly. Administrators create the rules that determine the sizes of derivatives. Editors save time as they can select an image from the DAM or upload one, and it will be automatically adapted to match the rule.
Edition | CE |
---|---|
License |
|
Issues |
|
Maven site |
|
Latest |
4.0.3 |
Installing with Maven
Maven is the easiest way to install the module. Add the following to your bundle:
<dependency>
<groupId>info.magnolia.imaging</groupId>
<artifactId>magnolia-imaging</artifactId>
<version>4.0.3</version> (1)
</dependency>
1 | Should you need to specify the module version, do it using <version> . |
Note the changes in |
Compatibility module
With Magnolia 5.6 we’ve begun removing the old Content API from our modules. If you have custom code relying on classes from the old imaging module then you must do one of two things:
-
Update your code for the new version of the imaging module.
-
Or you can use the
magnolia-imaging-compatibility
module together with themagnolia-core-compatibility
module.
Add the following snippet to your POM file:
<dependency>
<groupId>info.magnolia.imaging</groupId>
<artifactId>magnolia-imaging-compatibility</artifactId>
<version>4.0.3</version> (1)
</dependency>
1 | Should you need to specify the module version, do it using <version> . |
Image request processing
The diagram shows the elements of the Imaging module and how they interrelate (credit: Richard Unger).
-
info.magnolia.imaging.ImagingServlet is responsible for the actual generation of the images.
-
The info.magnolia.imaging.ImageGenerator interface is the entry point for generating images.
-
info.magnolia.imaging.operations.ImageOperationChain implements
ImageGenerator
and executes an operation chain. -
Various implementations of the info.magnolia.imaging.ParameterProviderFactory interface are responsible for instantiating parameter providers for a given environment.
-
Implementations of the info.magnolia.imaging.ImageStreamer interface are responsible for pushing the generated image, with the given generator and parameters, to an output stream.
Imaging servlet
info.magnolia.imaging.ImagingServlet is registered in the Magnolia
servlet
filter chain in /server/filters/servlets/ImagingServlet
. The servlet
is responsible for generating images.
Node name | Value |
---|---|
⸬ ImagingServlet |
|
⬩ enabled |
true |
⬩ servletName |
ImagingServlet |
⬩ class |
info.magnolia.cms.filters.ServletDispatchingFilter |
⬩ servletClass |
info.magnolia.imaging.ImagingServlet |
⬩ comment |
Imaging Servlet |
⸬ mappings |
|
⸬ -.imaging-- |
|
⬩ pattern |
/.imaging/* |
⸬ parameters |
Image generators
info.magnolia.imaging.ImageGenerator is a component that generates variants from a source image based on configuration. Generators are used by image provider classes to render images in the UI and on pages.
Generators are configured in {/modules/imaging/config/generators
.
Example: Generator configurations
Node name | Value |
---|---|
📁 generators |
|
⸬ default |
|
⬩ class |
info.magnolia.imaging.DefaultImageGenerator |
⸬ mte |
|
⬩ class |
info.magnolia.templating.imaging.ThemeAwareImageGenerator |
⸬ parameterProviderFactory |
|
⬩ class |
info.magnolia.templating.imaging.parameters.ThemeAwareParameterProviderFactory |
⸬ outputFormat |
|
⬩ quality |
80 |
⸬ large |
|
⬩ class |
info.magnolia.imaging.operations.ImageOperationChain |
⸬ outputFormat |
|
⬩ formatName |
jpg |
⬩ quality |
80 |
⸬ operations |
|
⸬ load |
|
⬩ class |
info.magnolia.imaging.operations.load.FromBinaryNode |
⸬ resize |
|
⬩ maxWidth |
500 |
⬩ class |
info.magnolia.imaging.operations.cropresize.BoundedResize |
⬩ maxHeight |
500 |
⸬ parameterProviderFactory |
|
⬩ class |
info.magnolia.imaging.parameters.BinaryNodeParameterProviderFactory |
⸬ portrait |
|
⬩ class |
info.magnolia.imaging.operations.ImageOperationChain |
⸬ outputFormat |
|
⬩ formatName |
jpg |
⬩ quality |
80 |
⸬ operations |
|
⸬ load |
|
⬩ class |
info.magnolia.imaging.operations.load.FromBinaryNode |
⸬ resize |
|
⬩ maxWidth |
240 |
⬩ class |
info.magnolia.imaging.operations.cropresize.BoundedResize |
⬩ maxHeight |
160 |
⸬ parameterProviderFactory |
|
⬩ class |
info.magnolia.dam.imaging.parameters.AssetAndBinaryNodeIdentifierParameterProviderFactory |
⸬ thumbnail |
|
⬩ class |
info.magnolia.imaging.operations.ImageOperationChain |
⸬ outputFormat |
|
⬩ formatName |
jpg |
⬩ quality |
90 |
⸬ operations |
|
⸬ load |
|
⬩ class |
info.magnolia.imaging.operations.load.FromBinaryNode |
⸬ resize |
|
⬩ maxWidth |
230 |
⬩ class |
info.magnolia.imaging.operations.cropresize.BoundedResize |
⬩ maxHeight |
230 |
⸬ parameterProviderFactory |
|
⬩ class |
info.magnolia.dam.imaging.parameters.AssetAndBinaryNodeIdentifierParameterProviderFactory |
Property | Description |
---|---|
|
required Generators configuration. |
|
required The name of the image generator.
|
|
required The image generator class:
|
|
required Output format configuration. |
|
required See the Parameter provider factory class. |
|
required (for See the Image operation chains configuration. |
Output format
The output format is the format or file type the generator produces,
such as JPEG or PNG. Supported formats are bmp
, gif
, jpeg
, png
, and webp
. The module also supports these formats and tiff
as
input formats.
Generation of WebP images from image sources that are not using the RGB color space is not supported. |
The output format is configured in /modules/imaging/generators/<generator name>/outputFormat
.
For the PNG format, only image compression is supported. The current implementation only supports PNG images with bit depths of 8 or 16. Compressing PNG images with a bit depth of 4 may result in a different byte size of the image. Converting a PNG image to a different image format is not possible. |
Property | Description |
---|---|
|
required Output format configuration. Defines the format the generator produces,
such as |
|
required Image quality as a percentage. |
|
optional (required only for The file extension of the generated images.
|
Parameter provider factory
Parameters are instructions passed to an operation, such as where to
load a source image or what text to lay over it. Registering
ParameterProviderFactory
allows you to pass parameters
from different sources:
The parameter provider factory is configured in
/modules/imaging/generators/<generator name>/parameterProviderFactory
.
Parameter provider classes:
|
Node-based |
|
Node-based |
|
Theme-aware |
|
Superclass for parameter provider factories based on workspace and path. |
|
Extracts workspace and identifier from path. Everything after the identifier is ignored. This allows you, for example, to pass a properly named filename to the image. |
Image operation chains
The Imaging module can resize and crop images, overlay text and apply
image filters. These are called image operations and are configured in
/modules/imaging/config/generators/<generator name>/operations
. Image
operations can also be configured in a theme.
An image operation chain consists of one or more operations. A simple chain could add only fixed text, while a more complex chain could load an image from a remote source, apply filters, add multiple text fields and style them differently.
Property | Description |
---|---|
|
required Name of the image generator. |
|
required Operations node. |
|
required One node for each operation in the chain, for example |
|
required Operation class |
|
required/optional Other properties supported by the operation class. The first operation in an operation chain is typically a load operation. Use info.magnolia.imaging.operations.load.FromBinaryNode to load an image from the DAM. |
Parameter provider factory and load operation class typing
Note that the ParameterProviderFactory
and ParameterProvider
implementations are typed. Let’s have a look at the interfaces:
-
ParameterProviderFactory: ParameterProviderFactory.java
-
ParameterProvider: ParameterProvider.java
The return type of For instance, info.magnolia.imaging.parameters.BinaryJcrNodePathParameterProviderFactory and info.magnolia.imaging.operations.load.FromBinaryNode work well together. |
Image subsampling
Image subsampling reduces an image’s resolution by skipping pixels instead of resizing them smoothly. The system selects every nth pixel rather than using all of them, making the image smaller while roughly preserving its appearance. Subsampling is useful for thumbnail images and for preventing very large images from using too much RAM.
To optimize memory usage when processing images, you can configure subsampling settings for relevant generators. You can set memory limits, target dimensions (width and/or height), or both, depending on your generator’s purpose and the actions defined in it.
Subsampling is supported for the following image formats: JPG, TIFF, BMP, GIF, and PNG. |
- Example: Subsampling using dimensions
-
If you set one of
subSampleWidth
orsubSampleHeight
to240
, the other is automatically adjusted to keep the original aspect ratio.-
Original image: 10315 x 7049 pixels (≈ 218 MB)
-
Subsampled image: 240 x 164 pixels (≈ 39 KB)
-
- Example 2: Subsampling using memory limits
-
If you set the
subSampleMemory
to20000000
(20 MB), the image dimensions are adjusted to ensure memory usage doesn’t exceed 20 MB while keeping the aspect ratio.-
Original image: 10315 x 7049 pixels (≈ 218 MB)
-
Subsampled image: 3123 x 2134 pixels (≈ 20 MB)
-
If only subSampleWidth or subSampleHeight is specified, the other adjusts automatically to maintain the image’s original aspect ratio.
If both memory and dimension limits are provided, the system first adjusts the image to fit within the memory limit and then resizes it to fit the target dimensions.
|
To enable and configure image subsampling, edit the Imaging module configuration in the Configuration app.
You can set different configuration nodes for each generator depending on your requirements.
The table below shows some sample nodes set for the portrait
generator, which generates thumbnails and previews:
Node name | Value |
---|---|
📁 generators |
|
⸬ portrait |
|
⸬ outputFormat |
|
⸬ operations |
|
⸬ load |
|
⬩ imageDecoder |
|
⬩ subSampleWidth |
500 |
⬩ subSampleHeight |
500 |
⬩ subSampleMemory |
20000000 |
⬩ class |
info.magnolia.imaging.operations.load.FromBinaryNode |
⸬ resize |
|
⸬ parameterProviderFactory |
|
⬩ class |
info.magnolia.imaging.operations.ImageOperationChain |
Property | Description |
---|---|
|
optional Container node for the subsampling configuration. |
|
optional, default is Maximum memory (in bytes) the image can occupy after subsampling. If the image exceeds this limit, it’s resized to fit within the limit while preserving the aspect ratio. Use |
|
optional, default is Target width for the subsampled image. Use |
|
optional, default is Target height for the subsampled image. Use |
|
optional, default is Controls behavior when subsampling is unsupported:
Subsampling is supported for the following image formats: JPG, TIFF, BMP, GIF, and PNG. |
Original and subsampled image dimensions and memory usage are logged at the DEBUG level under info.magnolia.imaging.operations.load.DefaultImageIOImageDecoder.
|
Create a custom generator
You can create a custom image generator If the defaults do not meet your requirements:
-
Subclass
ImageOperationChain
. -
Override
getOutputFormat()
method. -
Set the value of the
class
node to your class name.
Imaging workspace
The imaging engine stores generated images in the imaging
workspace.
The path where generated images are stored depends on info.magnolia.imaging.caching.CachingStrategy. The default path is:
/<generatorName> /<workspaceName> /<path of node or property (nodedata)>
For the MTE generator, the path is:
/mte /<themeName> /<variationName> /<path of node or property (nodedata)>
For example:
/mte /travel-demo-theme /960x720 /dam /tours /shark_brian_warrick_0824.JPG /jcr:content /generated image
When the image is rendered on a page, the URL to the generated image is:
/<CATALINA_HOME, contextPath> /.imaging (which is the Imaging servlet default path) /<generatorName> /<path to the cached image>
Here’s the same image generated by the portrait
and mte
generators
in the JCR Browser app. The
960x720
variation is configured in
the travel-demo-theme
.
View generated images
The syntax for the URL to request a generated image depends on the used ParameterProviderFactory. However, it usually has the following pattern:
<protocol>://<context>/.imaging/<generator name>/<specific parameters ...>
Here is an example of a path when using info.magnolia.imaging.parameters.BinaryJcrNodePathParameterProviderFactory:
<protocol>:<context>/.imaging/<generator-name>/<jcr-workspace-name>/<path-to-binary-node>.<suffix-according-to-output-type>
Image throttling
To regulate your imaging system under high load, you can configure the number of concurrent image generation requests and the allocated memory to throttle the process. When the system reaches its resource limits, new requests wait until resources free up. Resource limits are reached when there are either too many requests at once or not enough memory available.
You can also configure the wait time: requests can wait indefinitely (not recommended) or for a set timeout.
If requests exceed the timeout, they’re canceled and return a 503 Service Unavailable
error.
The values you configure depend on your project requirements and infrastructure.
Processing a single image typically requires 1.5 to 2 times its original size in memory, though actual usage depends on the image type and processing steps. For example:
|
To configure image throttling, you must edit your magnolia.properties
file and restart your instance.
magnolia.properties
examplemagnolia.imaging.max-memory=300000000 (1)
magnolia.imaging.max-requests=10 (2)
magnolia.imaging.max-wait=10000 (3)
1 | Example value of 300,000,000 bytes of memory allocated |
2 | Example value of a maximum of 10 concurrent requests |
3 | Example value of 10000 milliseconds wait time |
Property | Description |
---|---|
|
optional, default is Defines the maximum memory (in bytes) allocated for image processing across all requests.
Use If the image to be loaded exceeds the configured |
|
optional default is Specifies the maximum number of concurrent image generation requests.
Use |
|
optional default is Sets the maximum time (in milliseconds) a request waits for resources (memory and execution permit).
Use If resources aren’t granted within the |
Using Image subsampling also impacts memory requirements. It reduces the initial image size before loading and lowers overall memory consumption. |
Image throttling logs
Logging is managed by the info.magnolia.imaging.ImagingJobController log category.
When a new request arrives but there are insufficient resources, an INFO
-level log message provides details about the situation.
For example:
Waiting for resources - requested-memory: 1,458,600 bytes, current: [requests: 10/10, memory: 2,917,200 bytes /300,000,000, queue: 8]
This example log shows:
-
The job is requesting 1,458,600 bytes of memory for image processing (requested-memory).
-
10 requests are currently being processed, reaching the maximum limit of 10, while 8 additional requests are waiting in the queue.
-
The ongoing requests have allocated 2,917,200 bytes of memory out of the total available 300,000,000 bytes.
If a request has to wait, a follow-up message is logged once it’s granted the necessary resources. For example:
Resources granted - wait: 13ms, requested-memory: 1,458,600 bytes, current: [requests: 1 /10, memory: 1,458,600 bytes /300,000,000, queue: 8]
This example log shows:
-
The request waited 13 ms before resources became available.
-
The rest of the log message provides the updated system state, similar to the previous example.
-
The log level can be set to
DEBUG
to obtain additional details or assist with troubleshooting.
Caching
Magnolia caches image resources to improve performance. Any dynamic
images generated by the Imaging module are cached at two levels: in the
imaging
workspace and in the actual cache like any other page or
document. This means that once the system generates an image, you keep
getting the same cached image on subsequent requests.
During testing, you can disable caching of generated images completely.
In /modules/imaging/config
, create a new property named
storeGeneratedImages
and set the value to false
.
There is still a small delay between configuration changes and a new image being available. Magnolia’s observation mechanism intentionally waits a couple of seconds before reading a changed configuration. |
Imaging support
Imaging support is enabled by 3 Magnolia modules:
|
info.magnolia.imaging.ImagingSupport |
The support interface for imaging. |
|
info.magnolia.dam.imaging.ImagingBasedAssetRenderer |
Asset renderer that uses |
|
info.magnolia.templating.imaging.support.ThemeDelegatingImagingSupport |
ImagingSupport that delegates to a Theme. |
Image variations in a theme
A variation is a theme-specific configuration that defines the size of the target image and tells the imaging engine whether cropping is allowed. Variations are configured in a theme which allows you to configure image look and feel in the same place as CSS.
See Image variations and Displaying resized images for more.
Issues
Renditions of animated GIF images
In renditions of animated GIF images, only the first frame is resized and kept, turning the originally animated GIF image into a static GIF.
For the development status of this feature, see MGNLIMG-389 Allow GIFs to be used with Renditions.