Among the many features available for Digital Asset Management in the Nuxeo Platform is the ability to automatically compute several conversions of pictures and videos in different resolutions and formats. Recently I was asked if it is possible to have different conversions for a picture depending on the asset status and to add a watermark when the asset is expired. The Idea here is to keep the obsolete assets in the repository but prevent users from using them. My answer, of course, was yes! These requirements can easily be configured with Nuxeo Studio. Let’s see how.


Picture Asset Picture Asset

First, we need a converter which adds a watermark. ImageMagick provides several ways to do it and here we have chosen a command that scales the watermark to the right size in the target picture.

<extension target="org.nuxeo.ecm.platform.commandline.executor.service.CommandLineExecutorComponent"point="command">
<command name="addTextLayer" enabled="true">
<commandLine>convert</commandLine>
<parameterString>-background none -fill #{textColor} -gravity #{gravity} -size #{width}x#{height} caption:#{textValue} -rotate -25 #{sourceFilePath} +swap -gravity #{gravity} -composite #{targetFilePath}</parameterString>
<installationDirective>You need to install ImageMagick.
</installationDirective>
</command>
</extension>
<extension target="org.nuxeo.ecm.core.convert.service.ConversionServiceImpl"
point="converter">
<converter name="addTextLayer" class="org.nuxeo.ecm.platform.convert.plugins.CommandLineConverter">
<parameters>
<parameter name="CommandLineName">addTextLayer</parameter>
</parameters>
</converter>
</extension>

The next step is to configure an automation chain that uses our converter.


- Context.FetchFile
- Blob.RunConverter:
converter: pictureResize
parameters:
textValue: Rejected
targetFileName: watermarked.jpg
gravity: center
textColor: Red
strokeColor: Red
strokeWidth: "1"
conversionFormat: "@{ChainParameters[\"parameters\"].conversionFormat}"
height: "@{ChainParameters[\"parameters\"].height}"
width: "@{ChainParameters[\"parameters\"].width}"
depth: "@{ChainParameters[\"parameters\"].depth}"
- RunScript:
script: "lifecycle = pictureDocument.getCurrentLifeCycleState();\ntextValue = \"\";\nif (lifecycle == \"obsolete\") {\n textValue = \"\"+lifecycle.toUpperCase()+ \"\";\n}\nContext[\"textValue\"] = textValue;\n\n\n\n\n"
- Blob.RunConverter:
converter: addTextLayer
parameters:
textValue: "@{Context[\"textValue\"]}"
targetFileName: watermarked.jpg
gravity: center
textColor: Red
strokeColor: Red
strokeWidth: "1"
conversionFormat: "@{ChainParameters[\"parameters\"].conversionFormat}"
height: "@{ChainParameters[\"parameters\"].height}"
width: "@{ChainParameters[\"parameters\"].width}"

Finally, we need to override the default chain with the one we have configured previously.

<extension point="pictureConversions" target="org.nuxeo.ecm.platform.picture.ImagingComponent">
<!-- override default conversions -->
<pictureConversion chainId="image_compute_conversions" default="false" description="Thumbnail" id="Thumbnail" maxSize="100" order="0" rendition="true">
</pictureConversion>
<pictureConversion chainId="image_compute_conversions" default="false" description="Small" id="Small" maxSize="280" order="100" rendition="true">
</pictureConversion>
<pictureConversion chainId="image_compute_conversions" default="false" description="Medium" id="Medium" maxSize="550" order="200" rendition="true">
</pictureConversion>
<pictureConversion chainId="image_compute_conversions" default="false" description="Original Size" id="OriginalJpeg" order="400" rendition="true">
</pictureConversion>
</extension>

There is one remaining thing we need to configure. By default, the conversions are computed only if the main file changes. So we need to trigger the conversions when the asset status changes. For that we use an event handler and an automation chain.


Event handler which reacts to an asset becoming obsolete Event handler which reacts to an asset becoming obsolete

The event handler triggers the following automation chain:

- Context.FetchDocument
- Document.SetBlob:
file: "@{Document[\"file:content\"]}"
save: "true"
xpath: "file:content"

That’s it! Expired assets are now watermarked automatically!


Thumbnail View Thumbnail View

Detailed View Detailed View