Create Image Renditions in AEM

Create Image Renditions with an Event Handler


Create an event handler that creates image renditions after the image has been uploaded in your DAM.

Use Case

Generally, you can update your workflow launchers, or even extend them. In my case, I didn’t to modify the existent workflow because we had different projects on our instance. I remember I tried to extend it, but sometimes we got different errors, regarding some Oak conflicts and concurrency. For this reason, I came up with the idea to use an Event Handler that had to be triggered after the image had been uploaded.


Let’s create our Event Handler as follows:


import org.apache.commons.lang3.StringUtils;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

 * Created by r.teruzzi on 18/09/2019.
@Designate(ocd = UpdateAssetListener.UpdateAssetListenerConfiguration.class)
        service = EventHandler.class,
        immediate = true,
        enabled = true,
        property = {
                Constants.SERVICE_DESCRIPTION + "=Lab2020 Activation Event Listener ",
                EventConstants.EVENT_TOPIC + "=" + DamEvent.EVENT_TOPIC

public class UpdateAssetListener implements EventHandler {

    @ObjectClassDefinition(name = "Lab2020 - Event Handler for Update Asset Workflow")
    public @interface UpdateAssetListenerConfiguration {

                name = "List of Renditions",
                description = "Enter the renditions needed with the following format: 'width:height:false' e.g. '800:533:false"
        String[] getListOfRenditions();

    private ResourceResolverFactory resourceResolverFactory;

    private RenditionMaker renditionMaker;

    protected void activate(UpdateAssetListenerConfiguration config) {
        renditions = config.getListOfRenditions();

    private String[] renditions;
    private final Logger LOG = LoggerFactory.getLogger(getClass());

    public void handleEvent(Event event) {

        Object type = event.getProperty("type");
        if (type == DamEvent.Type.DAM_UPDATE_ASSET_WORKFLOW_COMPLETED) {
            String path = DamEvent.fromEvent(event).getAssetPath();
  "EVENT TYPE: " + type);
  "PATH: " + path);
            if (StringUtils.startsWith(path, "/content/dam/Lab2020")) { //The IF case is just an additional check
                //The resource should be null because the resource resolver should not has the permission for other paths except for costa-app
                try (ResourceResolver resourceResolver = Lab2020CommonMethods.getResourceResolver(resourceResolverFactory)) {
                    Resource resource = resourceResolver.getResource(path);
                    if (resource != null) {
                        Asset asset = resource.adaptTo(Asset.class);
                } catch (PersistenceException e) {
                    LOG.error("Failed to commit changes", e);

    private void createRenditions(Asset asset) {
        if (asset != null) {
            for (String rendition : renditions) {
                String[] renditionValues = rendition.split(":");
                if (renditionValues.length == 3) {
                    String renditionWidthValue = renditionValues[0];
                    int renditionWidth = Integer.parseInt(renditionWidthValue);
                    String renditionHeightValue = renditionValues[1];
                    int renditionHeight = Integer.parseInt(renditionHeightValue);
                    boolean center = Boolean.parseBoolean(renditionValues[2]);
                    RenditionTemplate thumbnailTemplate = renditionMaker.createThumbnailTemplate(asset,
                            renditionWidth, renditionHeight, center);
                    List<Rendition> renditions = renditionMaker.generateRenditions(asset, thumbnailTemplate);
                    for (Rendition r : renditions) {
                                .concat(renditionHeightValue).concat(".png"), r.getStream(), "image/png");


As you can see:

  • The event topic is: DamEvent.EVENT_TOPIC
  • But then the specific event type checked is related to the completed workflow: DamEvent.Type.DAM_UPDATE_ASSET_WORKFLOW_COMPLETED
  • The list of renditions has been configured. You could do the same for the list fo path or whatever you want like extensions and so on!
  • It’s been used a resource resolver associated with a system user with specific ACLs. If you don’t know how to create it, check this article.
  • The rendition maker service will do the job

That’s all guys! Here you can find different articles with some OSGi examples.

Cheers! 🥠


2 thoughts on “Create Image Renditions in AEM

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: