All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.aem.formsndocuments.util.ThumbnailUtil Maven / Gradle / Ivy

/*
  * ADOBE CONFIDENTIAL
  * __________________
  *
  *  Copyright 2016 Adobe Systems Incorporated
  *  All Rights Reserved.
  *
  * NOTICE:  All information contained herein is, and remains
  * the property of Adobe Systems Incorporated and its suppliers,
  * if any.  The intellectual and technical concepts contained
  * herein are proprietary to Adobe Systems Incorporated and its
  * suppliers and may be covered by U.S. and Foreign Patents,
  * patents in process, and are protected by trade secret or copyright law.
  * Dissemination of this information or reproduction of this material
  * is strictly forbidden unless prior written permission is obtained
  * from Adobe Systems Incorporated.
 */

package com.adobe.aem.formsndocuments.util;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.jcr.Node;
import javax.jcr.Session;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.sling.api.resource.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.aemforms.fm.exception.FormsMgrException;
import com.adobe.granite.asset.api.Asset;
import com.adobe.granite.asset.api.RenditionHandler;
import com.day.cq.commons.ImageHelper;
import com.day.cq.dam.api.thumbnail.ThumbnailConfig;
import com.day.cq.dam.commons.thumbnail.ThumbnailConfigImpl;
import com.day.cq.dam.commons.util.DamUtil;
import com.day.image.Layer;

public class ThumbnailUtil {
	
	private static final String RENDITION_TO_CREATE_THUMBNAIL = "cq5dam.thumbnail.319.319.png";
    private static final String THUMBNAIL_MIMETYPE = "image/png";
    private static final Collection thumbnailConfigs;
    private static final Logger log = LoggerFactory.getLogger(ThumbnailUtil.class);

    static {
        ThumbnailConfig config1 = new ThumbnailConfigImpl(140, 100, false);
        ThumbnailConfig config2 = new ThumbnailConfigImpl(48, 48, false);
        ThumbnailConfig config3 = new ThumbnailConfigImpl(319, 319, false);
        thumbnailConfigs = Arrays.asList(config1, config2, config3);
    }

	public static void addThumbnail(Resource res, Iterator members)throws IOException {
        int width = 319;
        int height = 319;
        Layer thumbnailLayer = new Layer(width, height, Color.WHITE);
        ArrayList memberLayers = new ArrayList ();
        int assetCount = 0;
        //Use 4 assets maximum to create a thumbnail
        while (members.hasNext() && assetCount < 4){
            Asset member = members.next();
            com.adobe.granite.asset.api.Rendition rendition = member.getRendition(RENDITION_TO_CREATE_THUMBNAIL);
            if (rendition != null) { //if the asset doesn't have rendition, we skip them
                Layer memberLayer = ImageHelper.createLayer(rendition);
                memberLayers.add(memberLayer);
                assetCount++;
            }
        }
        //Create composite thumbnail to be added as renditions
        for (int i = 0; i < memberLayers.size(); i++) {
            if (memberLayers.size() == 1) {
               thumbnailLayer = cropAsset(memberLayers.get(i), width, height);
            }
            else if (memberLayers.size() == 2) {
               Layer addedLayer =  cropAsset(memberLayers.get(i), width, height/2);
               int posY =  i * ( 1 + height / 2 );
               thumbnailLayer.drawImage(addedLayer.getImage(), null, 0, posY) ;
            }
            else if (memberLayers.size() > 2) {
                Layer addedLayer =  cropAsset(memberLayers.get(i), width / 2, height / 2 );
                int posX = (i % 2) * ( 1 + width / 2 );
                int posY = (i > 1 ? 1 : 0) * ( 1 + height / 2 );
                thumbnailLayer.drawImage(addedLayer.getImage(), null, posX, posY ) ;
            }
        }
        addThumbnailToAsset(res, thumbnailLayer);
    }
	
	public static void addThumbnailToAsset(Resource res, InputStream is) throws IOException{
		addThumbnailToAsset(res, new Layer(is));
	}
	
	private static void addThumbnailToAsset(Resource res, Layer thumbnailLayer) throws IOException{
		Asset asset = res.adaptTo(Asset.class);
		BufferedImage image = thumbnailLayer.getImage();
        File tmpFile = null;
        try {
            tmpFile = File.createTempFile("thumbnail", ".tmp");
            // order configs by size
            List cfg = new ArrayList(thumbnailConfigs);
            Collections.sort(cfg, new Comparator() {
                public int compare(ThumbnailConfig o1, ThumbnailConfig o2) {
                if (o1.getWidth() == o2.getWidth()) {
                    return o2.getHeight() - o1.getHeight();
                } else {
                    return o2.getWidth() - o1.getWidth();
                }
                }
            });
            Layer layer = null;
            for (final ThumbnailConfig config : cfg) {
                // reuse the layer for smaller thumbnails
                if (layer == null || config.getWidth() > layer.getWidth() || config.getHeight() > layer.getHeight()) {
                    if (layer != null) {
                        layer.dispose();
                    }
                    layer = new Layer(image);
                }
                Layer tLayer = createThumb(layer, config);

                OutputStream out = null;
                InputStream in = null;
                try {
                    out = FileUtils.openOutputStream(tmpFile);
                    tLayer.write(THUMBNAIL_MIMETYPE, 0.8, out);
                    IOUtils.closeQuietly(out);
                    in = FileUtils.openInputStream(tmpFile);
                    Map rhMap = new HashMap();
                	rhMap.put(RenditionHandler.PROPERTY_RENDITION_MIME_TYPE, THUMBNAIL_MIMETYPE);
                    asset.setRendition(DamUtil.getThumbnailName(config), in, rhMap);
                } finally {
                    IOUtils.closeQuietly(in);
                    IOUtils.closeQuietly(out);
                }
                // if image was centered, create a new layer for further processing
                if (tLayer != layer) {
                    tLayer.dispose();
                }
            }
        } finally {
            FileUtils.deleteQuietly(tmpFile);
        }
	}
	
	private static Layer cropAsset(Layer layer, int width, int height) {
        Rectangle cropRect = new Rectangle(0, 0, width, height);
        Layer outputLayer = new Layer(width, height, Color.WHITE);
        Layer cropLayer = layer;
        cropLayer.crop(cropRect);
        outputLayer.merge(cropLayer);
        return outputLayer;
	}
	
	private static Layer createThumb(Layer layer, final ThumbnailConfig config) {

        Layer finalLayer = null;
        final int maxWidth = config.getWidth();
        final int maxHeight = config.getHeight();
        final boolean doCenter = config.doCenter();
        final int width = layer.getWidth();
        final int height = layer.getHeight();
        final Color bgColor = layer.getBackgroundColor();

        if (height > maxHeight || width > maxWidth) {
            // resize image
            int newWidth, newHeight;
            if (height > width) {
                newHeight = maxHeight;
                newWidth = (width * maxHeight / height);
                if (newWidth > maxWidth) {
                    newWidth = maxWidth;
                    newHeight = (height * maxWidth / width);
                }
            } else {
                newWidth = maxWidth;
                newHeight = (height * maxWidth / width);
                if (newHeight > maxHeight) {
                    newHeight = maxHeight;
                    newWidth = (width * maxHeight / height);
                }
            }
            layer.resize(newWidth, newHeight, true);
        }

        // merge and center image so that the "requested" height and width
        // are respected
        if ((layer.getHeight() < maxHeight || layer.getWidth() < maxWidth) && doCenter) {

            final Color bg = (null != bgColor) ? bgColor : Color.WHITE;
            finalLayer = new Layer(maxWidth, maxHeight, bg);
            finalLayer.setTransparency(bg);
            int y = (maxHeight - layer.getHeight()) / 2;
            int x = (maxWidth - layer.getWidth()) / 2;
            layer.setX(x);
            layer.setY(y);
            finalLayer.merge(layer);
        }

        if (finalLayer == null) {
            return layer;
        } else {
            return finalLayer;
        }
    }

    /**
     * This utility return buffered image for thumbnail path
     * @param session
     * @param thumbnailPath
     * @return
     * @throws IOException 
     */
    public static BufferedImage getThumbnail(Session session, String thumbnailPath) throws IOException {
        BufferedImage image = null;
        InputStream is = null;
        try {
            if (session.nodeExists(thumbnailPath)) {
                Node imageNode = session.getNode(thumbnailPath);
                Node imageJcrContentNode = FMUtils.getContentNode(imageNode, false);
                if(imageJcrContentNode != null) {
                    is = imageJcrContentNode.getProperty(FMConstants.JCR_DATA_PROPERTY).getBinary().getStream();
                    image = ImageIO.read(is);
                } else {
                    log.error("Jcr node does not exist for " + thumbnailPath);
                }
            } else {
                log.error("Thumbnail is not present at " + thumbnailPath);
            }
        } catch (IOException e){
            log.error("failed to get thumbnail", e);
            throw e;
        } catch (Exception e) {
            log.error("failed to get thumbnail", e);
        } finally {
            IOUtils.closeQuietly(is);
        }
        return image;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy