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 DAM or upload one, and it will be automatically adapted to match the rule.

Download

The Imaging module is bundled with Magnolia and typically already installed. You can download it from our Nexus repository.

Installing

Imaging is a Community Edition module. It is typically already installed. Launch the Configuration app and go to /modules/imaging to check.

(warning) Create a backup of your system before you install a module. Uninstalling a module is not as simple as removing the .jar file. Modules add and change configurations and may change the content. Try new modules in a test environment first. A module consists of a JAR file and may include dependent JAR files. Modules are responsible for updating their own content and configurations across versions. Be sure to keep only one version of each module and its dependencies.

To install a module:

  1. Stop the application server.
  2. Copy the module JAR files into the WEB-INF/lib directory. The location of this directory depends on the application server.
    • Tomcat: /webapps/magnoliaAuthor/WEB-INF/lib
    • JBoss: /server/default/deploy/magnoliaAuthor/WEB-INF/lib
  3. Restart the server.
  4. Go to the AdminCentral URL.
  5. Start the Web update process.
  6. Click Start up Magnolia.

Repeat the steps for each author and public instance.

Uninstalling

To uninstall a module, remove the module JAR file from the /WEB-INF/lib folder and restart Magnolia.

(warning) However, this is rarely enough. Modules add and modify configuration during installation. The use of a module also changes content. Removing all of these changes is difficult without knowing the installation tasks in detail.

To test a module, use the embedded Derby database and take a backup of your repositories folder. Install the module and try it. When you are done testing, remove the module JAR and restore the repositories folder from the backup. This way you can go back to square one.

We also recommend that you segregate the development and production environments. Take regular backups for disaster recovery so you can revert to a prior state in a routine fashion.

Storing and generating digital assets

Magnolia's built-in digital asset management (DAM) 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-is 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 use. 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.

Features

The Imaging module:

  • Loads an image from the DAM, website, classpath or external URL.
  • Can start from an empty image canvas.
  • Resizes and crops. Original image is always kept.
  • Applies text overlays and filters.
  • Processes on the server, not on the client.
  • Makes derivative images available for caching strategies.
  • Allows you to implement your own image operations such as adding borders and drawing shapes.

The module also provides a framework to delegate image processing to an external non-Java system, providing a different caching mechanism.

Image request processing

The diagram shows the elements of the Imaging module and how they interrelate (credit: Richard Unger).

Configuration

Configuration for the Imaging module is at /modules/imaging/config.

Imaging servlet

ImagingServlet is registered in the Magnolia servlet filter chain at /server/filters/servlets/ImagingServlet. The servlet is responsible for generating images.

Node nameValue

 server

 

 filters

 

 context

 

 ...

 

 servlets

 

 ClasspathSpoolServlet

 

 ...

 

 ImagingServlet

 

 mappings

 

 -.imaging--

 

 pattern

/.imaging/*

 parameters

 

 class

info.magnolia.cms.filters.ServletDispatchingFilter

 comment

Imaging Servlet

 enabled

true

 servletClass

info.magnolia.imaging.ImagingServlet

 servletName

ImagingServlet

Image generator

Image generator is a component that generates variants from a source image based on configuration. Generators are configured at /modules/imaging/config/generators:

STKImageGenerator handles image generation for the Standard Templating Kit.

Node nameValue

 modules

 

 imaging

 

 config

 

 generators

 

 large

 

 outputFormat

 

 operations

 

 parameterProviderFactory

 

 class

info.magnolia.imaging.operations.ImageOperationChain

 portrait

 

 thumbnail

 

 stk

 

 outputFormat

 

 parameterProviderFactory

 

 class

info.magnolia.module.templatingkit.imaging.generation.STKImageGenerator

 

Input and output format

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. Supported formats (input and output) are bmp, gif, jpeg, jpg, png and wbmp. You can verify the formats available on your system by installing the Imaging Tools module from Nexus. The Tools > Image I/O plugins app displays 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.

    Node nameValue

     generators

     

     large

     

     outputFormat

     

     formatName

    jpg

     quality

    80

     operations

     

     parameterProviderFactory

     

     class

    info.magnolia.imaging.operations.ImageOperationChain

If you need a custom implementation for converting images from one format to another, create your own image generator:

  1. Subclass the STKImageGenerator class.
  2. Override the getOutputFormat() method.
  3. Set the value of the class node in configuration to your class' name.

Quality

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 quality property to the desired quality level. 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.

Progressive JPEGs

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.

Compression type

Imaging uses and delegates to javax.imageio.ImageWriteParam. This class supports a compressionType property that lets you choose which compression type to use.

Imaging workspace

The imaging engine stores generated images in the imaging workspace

The path where generated images are stored dependens on the  CachingStrategy . The default path 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
    /dam
      /demo-project
        /img
          /bk  
            /Opener
              /coral-light
                /jcr:content
                  /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.

 

Caching

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/parameters, create a new property storeGeneratedImages, and set its value to false.

Node nameValue

 server

 

 filters

 

 servlets

 

 ImagingServlet

 

 parameters

 

 storeGeneratedImages

false

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.

About resizing and cropping

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. Here's the zoom variation configuration used on the demo sites. You can find the configuration at STK > Themes/pop/imaging/variations/zoom.

Node nameValue

 pop

 

 cssFiles

 

 jsFiles

 

 imaging

 

 zoom

 

 crop

false

 height

600

 width

800

 promo

 

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

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.

  • 4:3 (1.33) is the original television picture ratio and most common in point-and-shoot digital cameras. Computer displays VGA, SVGA, XGA and UXGA are all 4:3. This ratio is also commonly used in embedded Web video players. You may need to create splash screen images for video. For example, Youtube's default embedded player sizes are 480x385 for a 4:3 video and 640x385 for 16:9.
  • 3:2 (1.5) is often used in DSLR cameras. The reason why DSLR image sensors are the flatter 3:2 instead of the taller point-and-shoot 4:3 is that DSLRs were designed to match the legacy 35mm SLR film whereas the majority of digital cameras were designed to match the predominant computer displays of the time.
  • 16:9 (1.78) is the international standard for HDTV, digital television and widescreen television, increasingly found in digital cameras too.

Device screen resolutions

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.

WidthHeightDevice
192010801080p, 1080i, HD DVD, Blu-ray
1280720720p, HD DVD, Blu-ray
1024768XGA, Apple iPad
1024600Used in many netbooks
960640Apple iPhone 4, 4th generation iPod Touch
854480Motorola Droid
800600SVGA, Amazon Kindle
800480WGA or WVGA, HTC Touch, Google Nexus One
640320Nokia Series 90 smartphones
480320HVGA, Apple iPhone 3G, iPod Touch

Display and text ad sizes

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.

Image operations

The Imaging module can resize and crop images, overlay text and apply image filters. These are called image operations. Operations are configured in Configuration >/modules/imaging/config/generators, or in the case of STK, in a theme using variations.

Image operation chain

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:

  • <operation chain name>: Arbitrary. Name of the operation chain.
    • operations: Individual operations go under this node. They are executed from top to bottom.
      • <first operation name>: Arbitrary. Name of first operation.            
      • <second operation name>: Arbitrary. Name of second operation.           
      • ......      
    • outputFormat: Defines the format for generated images.
    • parameterProviderFactory:    
      • class:  Fully qualified parameter provider factory class name. See Parameter providers below for alternatives.
    • class: ImageOperationChain registers the configuration as an image operation chain.

      Node nameValue
       modules 

       imaging

       

       config

       

       generators

       

       myOperationChain

       

       operations

       

       myOperation1

       

       myOperation2

       

       myOperation3

       

       outputFormat

       

       formatName

      jpg

       quality

      80

       parameterProviderFactory

       

       class

      info.magnolia.imaging.parameters.ContentParameterProviderFactory

       class

      info.magnolia.imaging.operations.ImageOperationChain

Parameters providers

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.
  • BinaryNodeParameterProviderFactory extracts workspace and UUID from the path. Everything after the uuid is ignored so that one can pass for example, a properly named filename to the image
  • STKParameterProviderFactory is an STK specific parameter implementation for the STK module.

Viewing images

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. If 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.

Creating an empty image canvas

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:

  1. Create an operation node emptyCanvas. The name is arbitrary, use any you like.
  2. Add three property nodes:
    1. class and set its value to info.magnolia.imaging.operations.load.Blank.
    2. height and set its value. Default is 200.
    3. width and set its value. Default is 200.
  3. Set outputFormat/formatName to png or jpg. PNG supports transparency so the engine creates a transparent PNG by default. Default JPG background color is black.
  4. Set parameterProviderFactory/class property to info.magnolia.imaging.parameters.ContentParameterProviderFactory.

    Node nameValue

     generators

     

     myOperationChain

     

     operations

     

     emptyCanvas

     

     class

    info.magnolia.imaging.operations.load.Blank

     height

    160

     width

    240

     outputFormat

     

     formatName

    png

     parameterProviderFactory

     

     class

    info.magnolia.imaging.parameters.ContentParameterProviderFactory

     class

    info.magnolia.imaging.operations.ImageOperationChain

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.

Loading an image from URL

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:

  1. Create an operation node loadFromURL.
  2. Add a property node class and set its value to info.magnolia.imaging.operations.load.URLImageLoader.
  3. Add property node url and set its value to the URL.

    Node nameValue

     generators

     

     myOperationChain

     

     operations

     

     loadFromURL

     

     class

    info.magnolia.imaging.operations.load.URLImageLoader

     url

    http://farm5.static.flickr.com/4052/4638137415_1f776215e8_m.jpg

     outputFormat

     

     parameterProviderFactory

     

     class

    info.magnolia.imaging.operations.ImageOperationChain

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.

Loading image from classpath

Use the ClasspathImageLoader class to load an image from the classpath. Pace 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:

  1. Copy your image file to /<CATALINA_HOME>/webapps/<contextPath>/WEB-INF/classes.
  2. Create an operation node loadFromClasspath.
  3. Add a property node class and set its value to info.magnolia.imaging.operations.load.ClasspathImageLoader.
  4. Add property node src and set its value to the name of the image files preceded by a forward slash.

    Node nameValue

     generators

     

     myOperationChain

     

     operations

     

     loadFromClasspath

     

     class

    info.magnolia.imaging.operations.load.ClasspathImageLoader

     src

    /bird-240.jpg

     outputFormat

     

     parameterProviderFactory

     

     class

    info.magnolia.imaging.operations.ImageOperationChain

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.

Resizing without cropping (BoundedResize)

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 and resize it to maximum width of 150. Width is the longer dimension so it is reduced to 150.

Properties:

  • <operation name>
    • classinfo.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. (warning) Magnolia 4.5.23+ / 5.2.9+ / 5.3.4+

Example: Resize without cropping:

  1. Create a folder myFolder in the Assets app.
  2. Upload a JPEG image into the folder and name it myImage.jpg.
  3. Copy the loadFromDAM operation used in Loading an image from DAM workspace above in the operations node. This is the first operation that provides an image to manipulate.
  4. Create a second operation node boundedResize.
  5. Add property node class and set its value to info.magnolia.imaging.operations.cropresize.BoundedResize.
  6. Add property node maxWidth and set its value to 150.
Node nameValue

 generators

 

 myOperationChain

 

 operations

 

 loadFromDAM

 

 class

info.magnolia.imaging.operations.load.FromContent

 propertyName

jcr:content

 boundedResize

 

 class

info.magnolia.imaging.operations.cropresize.BoundedResize

 maxHeight

120

 maxWidth

150

 outputFormat

 

 parameterProviderFactory

 

 class

info.magnolia.imaging.operations.ImageOperationChain

To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/dam/myFolder/myImage.jpg

Automated cropping and resizing (AutoCropAndResize)

AutoCropAndResize is an operation that 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 keeps 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:

  1. Create a folder myFolder in the Assets app.
  2. Upload a JPEG image into the folder and name it myImage.jpg.
  3. Copy the loadFromDAM operation used in Loading an image from DAM workspace above in the operations node. This is the first operation which provides an image to manipulate.
  4. Create a second operation node autoCropAndResize.
  5. Add property node class and set its value to info.magnolia.imaging.operations.cropresize.AutoCropAndResize.
  6. Add property node targetWidth and set its value to 150.
  7. Add property node targetHeight and set its value to 150.

    Node nameValue

     generators

     

     myOperationChain

     

     operations

     

     loadFromDAM

     

     class

    info.magnolia.imaging.operations.load.FromContent

     propertyName

    jcr:content

     autoCropAndResize

     

     class

    info.magnolia.imaging.operations.cropresize.AutoCropAndResize

     targetHeight

    150

     targetWidth

    150

     outputFormat

     

     parameterProviderFactory

     

     class

    info.magnolia.imaging.operations.ImageOperationChain

To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/dam/myFolder/myImage.jpg

Filters

Filters are standard Java BufferedImageOps that apply special effects to an image. The Imaging module ships with JH Labs Filters which can do:

  • Color adjustment
  • Distortion
  • Warping
  • Effects
  • Textures
  • Blurring
  • Sharpening
  • Edge detection
  • Transitions
  • Alpha channel

The BufferedImageOpDelegate class delegates the rendering to an image filter. Some filters have parameters that you can set in a correspondingly named property. See filter documentation on JH Labs website for filter class names and parameters. The source code for filters is included in the filters JAR that 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:

  1. EdgeFilter detects the edges in an image.
  2. GrayscaleFilter converts to grayscale.
  3. InvertFilter inverts the image colors.

To apply a filter:

  1. Start with an empty canvas or load an image to manipulate.
  2. Create a second operation node and name it after the filter so you remember what it does.
  3. Under the filter node:
    1. Add property class and set its value to info.magnolia.imaging.operations.BufferedImageOpDelegate.
    2. Add node delegate. This is the filter operation you delegate to. Add the following properties:
      1. class and set 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.
      1. Optional: If the filter supports parameters, add a property named after the parameter and set its value.

        Node nameValue

         generators

         

         myOperationChain

         

         operations

         

         emptyCanvas

         

         causticsFilter

         

         delegate

         

         amount

        0.9

         class

        com.jhlabs.image.CausticsFilter

         class

        info.magnolia.imaging.operations.BufferedImageOpDelegate

         outputFormat

         

         parameterProviderFactory

         

         class

        info.magnolia.imaging.operations.ImageOperationChain

To view the image, go to http://localhost:8080/magnoliaAuthor/.imaging/myOperationChain/dam/myFolder/myImage.png or another URL depending on how you load the base image.

Variations

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.

 


Credits:

  1. Talleda, Xavi (2007) "Speed"
  2. Unger, Richard (2012) "Enterprise extensions to Magnolia's Imaging module"
#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))