Email:       Twitter: @dbrucegrant

Leveraging ImageMagick with Nuxeo

Until recently I never really appreciated the value and power of ImageMagick. This is one slick piece of software (or collection of image transformation tools).

The base integration with Nuxeo is good, but there is still plenty of opportunity to improve. The need for speed (and flexibility) becomes very evident when dealing with 250MB images, TIF images, IPTC/EXIF/XMP metadata, and with images that have a CMYK color space.

Quick Fix...

ImageMagick is integrated with Nuxeo, or more accurately loosely bound to, via a series of command line calls that perform the image-related magic.  Nuxeo expects to find the ImageMagick tools on the system path, while the loose binding comes by way of a contribution that associates Nuxeo command names with ImageMagick commands and parameters. Part of the default Nuxeo contribution is shown below…

<?xml version="1.0"?>
<component name="org.nuxeo.ecm.platform.picture.commandline.imagemagick">
    <extension target="org.nuxeo.ecm.platform.commandline.executor.service.CommandLineExecutorComponent”
        <command name="identify" enabled="true">
            <parameterString> -ping -format '%m %w %h %z' #{inputFilePath}</parameterString>
            <winParameterString> -ping -format "%m %w %h %z" #{inputFilePath}</winParameterString>
            <installationDirective>You need to install ImageMagic.</installationDirective>


       <command name="resizer" enabled="true">
          <parameterString>-flatten -resize #{targetWidth}x#{targetHeight} -depth #{targetDepth} #{inputFilePath}[0]
          <installationDirective>You need to install ImageMagic.</installationDirective>

I included this chunk of code because it demonstrates an issue with ImageMagick and the flexibility of Nuxeo (and ImageMagick) to address the issue.

In the example, the Nuxeo “resizer” command gets tied to the ImageMagick “convert” command. If the input picture is a TIF file then resizer will convert the image to a JPG and resize as required. This causes a problem when the TIF image has layers/masks. Unfortunately, converting from TIF to JPEG and resizing at the same time results in the loss of layers/masks in the resulting JPEG image – not so good.

There is a workaround, and that involves splitting the resizer command into two parts. Luckily both Nuxeo and ImageMagick are fine with using pipe-lined commands. So, what I split the single default resizer command into a conversion and then a re-size. I overrode the existing contribution with the following….

<command name="resizer" enabled="true">
     <parameterString> #{inputFilePath}[0] jpg:- | convert - -resize #{targetWidth}x#{targetHeight} –depth
                                    #{targetDepth} #{outputFilePath}</parameterString>
     <installationDirective>You need to install ImageMagick</installationDirective>

In the new “resizer” the input file first gets converted to a JPEG file (represented by the -), which is then piped into a convert command to resize the JPEG as required. This may cause slightly more work, but TIF files now get converted and resized as expected.

Resolving the TIF conversion issue with a simple contribution is a fairly simple solution.

One or the Other...

Unfortunately, not all fixes are so straight forward. The “CropAndResize” command is used by the tiling service to facilitate annotations. Crop and resize issues a pipelined ImageMagick command (stream | convert … see below) that takes an input stream and converts the image to a specified size using a given color map. Problem is – the color map is hardcoded as RGB – which is an issue for any image in a CMYK color space.

<command name="cropAndResize" enabled="true">
      <parameterString> -map rgb -storage-type char -extract #{tileWidth}x#{tileHeight}+#{offsetX}+#{offsetY}
                                    #{inputFilePath} - | convert -depth 8 -size #{tileWidth}x#{tileHeight} -resize
                                    #{targetWidth}x#{targetHeight}! rgb:- #{outputFilePath} </parameterString>
      <installationDirective>You need to install ImageMagic.</installationDirective>

The –map rgb in the cropAndResize command can be changed to –map cmyk (and the piped output changed to cmyk:-) … and CMYK images will now appear properly for annotations. However, RGB images are no longer tiled correctly. In this case programmatic changes are required to determine the color space of the image being processed and then to pass the appropriate color map value to cropAndResize as a parameter.  Getting the color space could be part of an existing Identify command (where all image objects are picked up) or it could be done in a separate process using “identify –format %[colorspace] filename.tif” (although this will incur extra processing costs).

To make this work the image tiling package and imaging core package need to be modified.

Big Image Efficiencies... next time

Finally, when it comes to dealing with big files in Nuxeo (100MB+) there is room for improvement. I haven’t yet walked through the whole process but I have watched the number of temp files that get created during the ingestion process. At first blush it appears that there is an opportunity to make this more efficient – which is really important for large files! However, I will have to dig into this another time.

Add Comment

Really nice blog bruce! Have you considered doing pull request on our github?

Posted on 3/14/12 6:36 AM.

Post Reply Top
Good idea - time to git going on this... after a frustrating day patching my linux box with everything imaginable the clone is finally underway!

Posted on 3/14/12 8:08 PM in reply to .

Post Reply Top

Recent Entries Recent Entries

RSS (Opens New Window)
Showing 1 - 5 of 15 results.
of 3