Magnolia 4.5 reached end of life on June 30, 2016. This branch is no longer supported, see End-of-life policy.
The Imaging module simplifies working with images. You don't need to resize and crop each image for teasers and openers by hand. Instead, upload a single source image into the system and let 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 DMS or upload one, and it will be automatically adapted to match the rule.
Download the module from Magnolia Store or Nexus repository.
Imaging is a Community Edition module. It is included in the Standard Templating Kit module bundle and typically already installed. Go to Magnolia Store > Installed modules in AdminCentral to check. To install the module individually follow the general module installation instructions .
See the general module uninstalling instructions and advice.
Magnolia's built-in document management system (DMS) stores images as reusable resources. The stored version of an image is generally the largest and highest quality image available. The source is typically too large to be used on the site as such so related proxy copies are created. A proxy copy is a lower resolution representation of the source image that can be used in teasers and features to reduce bandwidth requirements.
The Imaging module creates a proxy copy from the source image on-the-fly when the image is requested for the first time and retains the proxy copy for subsequent uses. A teaser image is a typical example. It is a small version of the image in the teased article. The Imaging module creates the teaser image according to a pre-configured variation rule. An editor who adds a teaser on a page does not need to manipulate the image. The system knows which image is used on the teased page and creates a resized variation of it automatically.
The Imaging module:
The module also provides a framework to delegate image processing to an external non-Java system, providing a different caching mechanism.
The diagram shows the elements of the Imaging module and how they interrelate (credit: Richard Unger).
ImagingServlet
is responsible for the actual generation of the images.ImageGenerator
interface is the entry point for generating images.ImageOperationChain
implements ImageGenerator
and executes an operation chain.ParameterProviderFactory
interface are responsible for instantiating parameter providers for a given environment.ImageStreamer
interface are responsible for pushing the generated image, with the given generator and parameters, to an output stream.Configuration for the Imaging module is in Configuration > /modules/imaging/config
.
ImagingServlet
is registered in the Magnolia servlet filter chain at /server/filters/servlets/ImagingServlet
. The servlet is responsible for generating images.
Magnolia 4.5.4+/Imaging 2.2.4+ Set the
validateFileExtension
parameter property to true
to return a 404 (Not Found) error for image requests with the incorrect extension. Default is false
.
Image generator is a component that generates variants from a source image based on configuration. Generators are configured in Configuration > /modules/imaging/config/generators/stk
. The Imaging module ships with STKImageGenerator
which handles image generation for the Standard Templating Kit. This is the most commonly used generator. ImageOperationChain
is a generator that executes operation chains.
Format refers to the file format the imaging system accepts as an input source and the format the generator produces, such as JPEG or PNG. To find out which formats are available on your system, install the Imaging Tools module from Nexus and go to Tools > Image I/O plugins in AdminCentral to see a list of supported file extensions.
Output format is configured differently depending on the image generator:
ImageOperationChain
reads the formatName
property for the desired output format. Set the value of this property to a lowercase file extension such as jpg
or png
. The module will save the generated images in this format even if the source format is different.STKImageGenerator
always generates images in the same format as the source image. So if you upload a jpg, this generator will produce a jpg. This is an STK specific implementation.If you need a custom implementation for converting images from one format to another, create your own image generator:
STKImageGenerator
class.getOutputFormat()
method.class
data node in configuration to your class' name.JPEG is a lossy image format. It compresses image data by discarding (losing) some of it with the aim of minimizing the amount of data needed to store and transfer the image. The degree of compression can be adjusted, allowing a tradeoff between bandwidth consumption and image quality.
Set the desired level of quality with the quality
property. Magnolia uses a percentage-based scale from 0 to 100. Default is 80%. The higher the quality, the less compression is applied during JPEG creation. Compression is always applied in JPG. Some of the original image information is always lost in compression and cannot be restored, possibly affecting image quality. Quality 100 simply means that the system uses the least possible amount of compression, favoring good quality. 0 means maximum compression. Many Magnolia imaging properties such as quality
map to the corresponding methods in javax.imageio.ImageWriteParam.
Image at 80% quality.
Image at 10% quality.
In a progressive JPEG, data is compressed in multiple passes of progressively higher detail. A progressive JPEG has the same quality as a baseline JPEG but displays the image while it is being downloaded, at the cost of a slight increase in file size.
Progressive processing is suited for large images and slow connections. Visitors can see a reasonable preview after receiving only a portion of the image data. If your site uses large images extensively in an image gallery or slideshow, set the progressive
property to true
and see if it improves the user experience. Default value is false
which yields baseline (non-progressive) JPEGs.
Imaging uses and delegates to javax.imageio.ImageWriteParam
. This class supports a compressionType
property that lets you choose which compression type to use.
The imaging engine stores generated images in the imaging
workspace. To access this workspace, configure a custom JCR Browser or go to http://<domain>/<context Path>/.magnolia/tress/imaging
, typically at http://localhost:8080/magnoliaAuthor/.magnolia/trees/imaging
.
The path in which generated images are stored is dependent on info.magnolia.imaging.caching.CachingStrategy
. The default is:
/<generatorName> /<workspaceName> /<path of node or property (nodedata)>
For STK, the path is:
/<themeName> /<variationName> /<workspaceName> /<path of node or property (nodedata)>
For example:
/pop /promo /dms /demo-project /img /bk /Opener /coral-light /document /generated-image
When the image is rendered on a page, the URL to the generated image is:
/<hostName, contextPath> /.imaging (which is the Imaging servlet default path) /<generatorName> /<path to the cached image>
Here is example image with the URL highlighted. Compare the URL to the path above.
If you are not working on a standard installation, replace localhost:8080/magnoliaAuthor
with <your domain>/<context path>
in all URLs in the rest of this document.
Magnolia caches image resources to improve performance. Any dynamic images generated by the Imaging module are also 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. Go to Configuration > /server/filters/servlets/ImagingServlet
, create a new property storeGeneratedImages
, and set its value to false
.
You can also delete the generated images with the JCR Browser. Configure a custom JCR Browser for the imaging
workspace and delete the nodes as you normally would. However, this will slow you down as you need to keep deleting them as you work through the examples and the system keep generating new cached copies. So disabling the cache is preferred during development.
Note that there is still a small delay between any change you make to image configuration and a new image being available. Magnolia's observation mechanism intentionally waits couple of seconds before reading a changed configuration.
The most common image operation is resizing, particularly downsampling. In this process a larger source image is reduced to produce a smaller image for use in teasers and promos. You can also upsample images but be aware that the pixels become increasingly visible, making the image appear "soft".
Cropping removes unwanted areas from an image. The optional crop
property in a variation determines whether cropping should happen.
The default value is true
which means images will be cropped to accommodate the target dimensions. Cropping is done symmetrically from both sides of the image, focusing on what is in the middle. (Dog photo credit: Xavi Talleda)
If you set crop
to false
the engine will not crop the image. The image is resized to the smaller of the two target dimensions while constraining the dimensions. For example, if the original image is 1024 x 800 and you specify a target size 480 x 320 and set crop
to false
, the engine will create an image that is 410 x 320. The image has the same aspect ratio (1.28:1) as the original. Height is the smaller dimension (going from 800 to 320 is a 60% reduction whereas going from 1024 to 480 is a 53% reduction) so height is targeted.
The engine calculates the new width as follows:
target long edge = source long edge / source short edge * target short edge = 1024 / 800 * 320 = 409.6 ≈ 410 (rounded to nearest full pixel)
Aspect ratio refers to the width of the image compared to its height. You should know common aspect ratios in digital photography and video since your source images probably adhere to them.
You may also need to target images for specific device screen resolutions. Here are some common resolutions. Note that a mobile devices is commonly held in portrait orientation, so the iPhone resolution 480x320 is actually more often 320x480.
Width | Height | Device |
---|---|---|
1920 | 1080 | 1080p, 1080i, HD DVD, Blu-ray |
1280 | 720 | 720p, HD DVD, Blu-ray |
1024 | 768 | XGA, Apple iPad |
1024 | 600 | Used in many netbooks |
960 | 640 | Apple iPhone 4, 4th generation iPod Touch |
854 | 480 | Motorola Droid |
800 | 600 | SVGA, Amazon Kindle |
800 | 480 | WGA or WVGA, HTC Touch, Google Nexus One |
640 | 320 | Nokia Series 90 smartphones |
480 | 320 | HVGA, Apple iPhone 3G, iPod Touch |
Ad elements adhere to standard sizes on the Web. Google AdSense provides a nice overview of the different ad elements and their sizes in case you need to generate images for this purpose.
The imaging module can resize and crop images, overlay text and apply image filters. These are called image operations. Operations are configured in /modules/imaging/config/generators
or, in the case of STK, in a theme using variations.
An image operation chain consists of one or more operations. A simple chain can just add some fixed text while a more complex chain can load an image from a remote source, apply filters, add multiple text fields and style them differently. At minimum, an image operation chain must have this structure:
Mandatory nodes and properties:
Node | Value |
---|---|
| Name of the operation chain. You can choose. |
| Individual operations go under this content node. They are executed from top to bottom. |
|
|
|
|
|
|
| Defines the format for generated images. |
| File format extension: jpg, png, gif, tif. |
| JPEG quality as a percentage. Default is |
|
|
|
|
|
|
ImageOperationChain
registers the configuration as an image operation chain.
Parameters are instructions passed to an operation, such as where to load a source image or what text to lay over it. Registering a ParameterProviderFactory allows you to pass parameters from different sources:
ContentParameterProviderFactory
determines the workspace and image node to use based on the request URI. It assumes that the first path element is the name of the image generator or the operation chain, the second is the name of the workspace where the source image node is, and that the rest is the path to the node.STKParameterProviderFactory
is an STK specific parameter implementation for the STK module.alt
attributesSee setting alt
attributes in the Document Management section.
Generic syntax for the URL of the generated image is:
http://localhost:8080/magnoliaAuthor/.imaging/<chain name>/<workspace>/<path to image>
All examples below are variations for this URL and an example URL is provided for each. The /<workspace>/<path to image>
part is dependent on the parameter provider. As seen in Imaging workspace above, STK decodes this part slightly differently.
Remember that generated images are cached. You keep getting the same image back even if you modify the examples below. Disable caching of copies so you can be sure to get a new image, then refresh the URL.
The simplest image operation is to create an empty canvas. This operation does not use an existing image as a starting point but creates a completely new one.
To create an empty canvas:
emptyCanvas
. The name is arbitrary, use any you like.class
and set its value to info.magnolia.imaging.operations.load.Blank
.height
and set its value. Default is 200.width
and set its value. Default is 200.formatName
to png
or jpg
. PNG supports transparency so the engine creates a transparent PNG by default. Default JPG background color is black.To view the PNG image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/website/demo-project/about.png
. Since a transparent PNG is hard to see, paint over the page with your mouse to see the image outline.
To view the JPG image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/website/demo-project/about.jpg
.
The website page, in this case /demo-project/about
, must exist in the website
workspace because this is how the ContentParameterProviderFactory
works.
The FromContent
class can load an image from the dms
or website
workspace. It just loads the image, no other operations are performed. This is probably the most common use case to start with. The propertyName
property identifies where the image should be loaded, in this example from the DMS.
Store an image in DMS:
myFolder
in the DMS.myImage.jpg
.Load image from DMS:
loadFromDMS
. The name is arbitrary, use any you like.class
and set its value to info.magnolia.imaging.operations.load.FromContent
.propertyName
and set its value to document
.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/dms/myFolder/myImage.jpg
.
The FromContent
class can also load an image from the website
workspace. This example loads an image that was uploaded on a page. The propertyName
property identifies the node that stores the uploaded image. The URL to view the generated image must contain the path to the page.
Upload an image to a page:
/demo-project/about
.Find the property that stores the image:
/demo-project/about
.imageBinary
.Load the image from website:
loadFromWebsite
.class
and set its value to info.magnolia.imaging.operations.load.FromContent
.propertyName
and set its value to imageBinary
.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/website/demo-project/about.jpg
.
Use the URLImageLoader
class to load an image from an external URL. Identify the URL with the url
property. This example uses http://farm5.static.flickr.com/4052/4638137415_1f776215e8_m.jpg.
Load the image from URL:
loadFromURL
.class
and set its value to info.magnolia.imaging.operations.load.URLImageLoader
.url
and set its value to the URL.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/website/demo-project/about.jpg
.
The website page, in this case /demo-project/about
, must exist in the website
workspace because this is how the ContentParameterProviderFactory
works.
To load an image from the classpath, place the source image in the classpath of the webapp. By default, a Magnolia webapp's classpath contains JARs in /WEB-INF/lib
and any classes and resources in /WEB-INF/classes
. Magnolia will find any image you place in those locations.
Load image from classpath:
/apache-tomcat/webapps/magnoliaAuthor/WEB-INF/classes
.loadFromClasspath
.class
and set its value to info.magnolia.imaging.operations.load.ClasspathImageLoader
.src
and set its value to the name of the image files preceded with a forward slash.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/website/demo-project/about.jpg
.
The website page, in this case /demo-project/about
, must exist in the website
workspace because this is how the ContentParameterProviderFactory
works.
BoundedResize
is an operation that resizes an existing image without cropping. It resizes the image to either maxHeight
or maxWidth
while honoring the aspect ratio. In this example we first load a 240 x 160 image from the DMS and resize it to maximum width of 150. Width is the longer dimension so it is reduced to 150.
Properties:
class
: info.magnolia.imaging.operations.cropresize.BoundedResize
maxHeight
: Target image maximum height.maxWidth
: Target image maximum width.expand
: Optional. Set to false
to prevent upsampling. If reaching the target dimension would require upsampling a small source image, don't do anything. Upsampling often leads to fuzzy images. When set to false
the BoundedResize operation leaves the image as is. Default value is true
which allows upsampling. Example: Resize without cropping:
myFolder
in the DMS.myImage.jpg
.loadFromDMS
operation used in Loading an image from DMS workspace above in the operations
content node. This is the first operation which provides an image to manipulate.boundedResize
.class
and set its value to info.magnolia.imaging.operations.cropresize.BoundedResize
.maxWidth
and set its value to 150
.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/dms/myFolder/myImage.jpg
.
AutoCropAndResize
is an operation which resizes an existing image to targetWidth
and targetHeight
, cropping it if needed. Instead of the original aspect ratio it honors the target aspect ratio. It crops the image so that the largest possible portion of is kept. It will keep the center part of the image and cuts out from the sides.
If you define only targetWidth
or only targetHeight
, no cropping is done. Cropping happens only when you define both targetWidth
and targetHeight
and their ratio does not match the source ratio.
In this example a 240 x 160 image is auto-cropped and resized to 150 x 150 (a square). Since the original was not a square the resulting image is cropped to match the target ratio. The sides of the image are cut off.
Note how the subject of the image, the dog, is also cut. This is typically not an issue when using mood images that don't have specific focal point which should always be visible. It may be an issue for portraits and product images.
The same rules apply to upscaling: defining target dimensions that are larger than the original creates an enlarged copy. If the ratio of the target dimensions does not match that of the original, cropping happens.
To auto-crop and resize:
myFolder
in the DMS.myImage.jpg
.loadFromDMS
operation used in Loading an image from DMS workspace above in the operations
content node. This is the first operation which provides an image to manipulate.autoCropAndResize
.class
and set its value to info.magnolia.imaging.operations.cropresize.AutoCropAndResize
.targetWidth
and set its value to 150
.targetHeight
and set its value to 150
.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/dms/myFolder/myImage.jpg
.
Text overlays are used for dynamic graphics that combine text and an image. The advantage is that creative image work can be done ahead of time by a graphic designer while textual changes can be done anytime by an editor, or even automated. There is no need to change the graphic in order to adjust the message. Designers can provide editors with an image template that leaves certain areas blank to fill in dynamic text such as pricing and marketing messages.
Here are some ideas how to use text overlays:
The text overlay mechanism does not generate alt
attributes for the images. This means that the text in the image is not available for search engines to index. This is typically not a problem for short-term, transient content that is not intended to be indexed and searchable. However, if your image text is intended for long-term use and you want SEO benefits, use a component that overlays the text with CSS. The Stage component in STK is an example of an SEO-friendly overlay.
FixedText
overlay renders any text provided in the text
property on top of the image. You can start with an empty canvas or load an existing image.
The text starts from the bottom left corner, the origin (0,0) of the coordinate system, and extends to the right. The baseline of the text sits on the horizontal axis by default. This means that any part of the typeface that falls below the baseline falls also outside the image.
Fixed text overlay supports the following parameters.
Property | Description | Default value |
---|---|---|
| Text to render, for example "20% off selected items". Mandatory. |
|
| Text offset from left in pixels. |
|
| Text offset from bottom in pixels. |
|
| Horizontal alignment: |
|
| Vertical alignment: |
|
| Content node that contains style properties |
|
| Font color. Valid values include names ( |
|
| Font name, for example |
|
| Typeface style. |
|
| Font size in points, for example |
|
In this example a 240 x 160 empty canvas is generated as a basis. On top of that, we add fixed text "Simple is Beautiful" in 26-point black Helvetica font. Since no horizontal or vertical offsets are specified the text starts from the original (0,0). No alignment values are specified either so they default to left
and bottom
. The descender part of letter "p" falls below the baseline and is cut off.
In this example a 240 x 160 image is loaded from the DMS as a basis. On top of that, we add fixed text "Simple is Beautiful" in 25-point white Casual font with bold italic typeface. Horizontal alignment is set to center
and vertical offsets to 20 pixels. This time the complete text is displayed.
To add a fixed text overlay:
myFolder
in the DMS.myImage.jpg
.loadFromDMS
operation used in Loading an image from DMS workspace above in the operations
content node. This is the first operation which provides an image to manipulate.fixedText
.fixedText
:class
and set its value to info.magnolia.imaging.operations.text.FixedText
.text
and set its value to any text you want to display.x
and set its value to text offset from bottom in pixels.y
and set its value to text offset from left in pixels.horizontalAlign
and set its value to left
, center
or right
.verticalAlign
and set its value to bottom
, middle
or top
.textStyle
.textStyle
color
and set its value to a color name or hex value.fontName
and set its value to a valid font name.fontSize
and set its value to an integer point size.fontStyle
and set its value to: 0
, 1
, 2
or 3
. See table above.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/dms/myFolder/myImage.jpg
.
TextFromNode
loads text from a content node. The advantage is that you can use website content in the image: component titles, events, data item values or even values from an external source retrieved with an RSS aggregator.
TextFromNode overlay supports the following parameters:
Property | Description | Default value |
---|---|---|
| Property of content node that contains the text, for example |
|
| Text offset from left in pixels. |
|
| Text offset from bottom in pixels. |
|
| Horizontal alignment: |
|
| Vertical alignment: |
|
| Content node that contains style properties |
|
| Font color. Valid values include names ( |
|
| Font name, for example |
|
| Typeface style. |
|
| Font size in points, for example |
|
Path to the content node, such as a web page, is passed in the request URI. This is how ContentParameterProviderFactory
works by default. The property of the content node that contains the text to render is passed in the propertyName
parameter. The system combines these two parameters to retrieve text.
For example, to retrieve the abstract of the About page you would request with a URI such as:
http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/website/demo-project/about.jpg
while setting the propertyName
value to abstract
.
Note how the text flows over the right edge of the image. If you need to wrap long text onto multiple lines, extend the BasicTextRenderer
class.
To add a TextFromNode overlay:
loadFromWebsite
operation used in Loading an image from website workspace into the operations
content node. This is the first operation which provides an image to manipulate.textFromNode
.textFromNode
:class
and set its value to info.magnolia.imaging.operations.text.TextFromNode
.propertyName
and set its value to abstract
. This is the abstract text of the About page.x
and set its value to text offset from bottom in pixels.y
and set its value to text offset from left in pixels.horizontalAlign
and set its value to left
, center
or right
.verticalAlign
and set its value to bottom
, middle
or top
.textStyle
.textStyle
color
and set its value to a color name or hex value.fontName
and set its value to a valid font name.fontSize
and set its value to an integer point size.fontStyle
and set its value to: 0
, 1
, 2
or 3
. See table above.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/website/demo-project/about.jpg
.
Filters are standard Java BufferedImageOps that apply special effects to an image. The Imaging module ships with JH Labs Filters which can do:
The BufferedImageOpDelegate
class delegates the rendering to an image filter. Some filters have parameters that you can set in a correspondingly named data node. See filter documentation on JH Labs website for filter class names and parameters. The source code for filters is included in the filters
JAR which ships with the Imaging module.
In this example we apply three consecutive filters on the street light image used in Loading an image from URL above:
To apply a filter:
class
and set its value to info.magnolia.imaging.operations.BufferedImageOpDelegate
.delegate
. This is the filter operation you delegate to.delegate
:class
and set its value to fully-qualified filter class name, for example com.jhlabs.image.CausticFilter
. All JH Labs filters start with com.jhlabs.image
. Find the class name in JH Labs documentation.To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/dms/myFolder/myImage.jpg
or another URL depending on how you load the base image.
A variation is an STK 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 rather than under the Imaging module config
node. This way you can configure image look and feel aspects in the same place as CSS.
For more information on STK variations see Themes > Image variations.