
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