
com.day.cq.dam.commons.thumbnail.ThumbnailGenerator Maven / Gradle / Ivy
/*
* Copyright 1997-2008 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.cq.dam.commons.thumbnail;
import static com.day.cq.dam.api.DamConstants.THUMBNAIL_MIMETYPE;
import java.awt.Color;
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.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.thumbnail.ThumbnailConfig;
import com.day.cq.dam.commons.util.DamUtil;
import com.day.cq.dam.commons.util.OrientationUtil;
import com.day.image.Layer;
/**
* Generates thumbnails for the given {@link Asset} and its graphical representation in the form of a {@link
* BufferedImage}. Thumbnails are generated based on a collection of {@link ThumbnailConfig}s.
*
* @see com.day.cq.dam.api.thumbnail.ThumbnailConfig
* @since CQ 5.4.0
*
* @deprecated since 6.0, use {@link com.day.cq.dam.api.renditions.RenditionMaker} service instead
*/
@Deprecated
public class ThumbnailGenerator {
private static final Logger log = LoggerFactory.getLogger(ThumbnailGenerator.class);
private final Asset asset;
private final BufferedImage image;
/**
* Constructor for the ThumbnailGenerator
.
*
* @param asset The {@link com.day.cq.dam.api.Asset} for which thumbnails shall be generated.
* @param image The {@link BufferedImage} serving as the graphical representation of the asset, from which
* thumbnails are generated.
*
* @deprecated since 6.0, use {@link com.day.cq.dam.api.renditions.RenditionMaker} service instead
*/
@Deprecated
public ThumbnailGenerator(final Asset asset, final BufferedImage image) {
this.asset = asset;
this.image = image;
}
/**
* This method creates the thumbnails denoted by the given configs
and stores it as {@link
* com.day.cq.dam.api.Rendition}s on the asset. Thumbnails are saved in batch mode to the asset.
*
* @param configs The thumbnail configurations.
* @throws java.io.IOException If an error occurred processing the image.
* @throws javax.jcr.RepositoryException in case the thumbnails cannot be persisted
*
* @deprecated since 6.0, use {@link com.day.cq.dam.api.renditions.RenditionMaker} service instead
*/
@Deprecated
public void generate(final Collection configs)
throws IOException, RepositoryException {
File tmpFile = null;
final boolean oldBatchMode = asset.isBatchMode();
asset.setBatchMode(true);
try {
tmpFile = File.createTempFile("thumbnail", ".tmp");
// order configs by size
List cfg = new ArrayList(configs);
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);
// rotate image according to orientation metadata
OrientationUtil.adjustOrientation(asset, layer);
}
Layer tLayer = createThumbnail(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);
asset.addRendition(DamUtil.getThumbnailName(config), in, THUMBNAIL_MIMETYPE);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
// if image was centered, create a new layer for further processing
if (tLayer != layer) {
tLayer.dispose();
}
}
try {
if (!asset.isBatchMode()) {
asset.adaptTo(Node.class).getSession().save();
}
} catch (RepositoryException e) {
String msg = "generate: error while saving changes for asset [" +
asset.getPath() + "]: ";
log.debug(msg, e);
throw new RepositoryException(msg, e);
}
} finally {
asset.setBatchMode(oldBatchMode);
FileUtils.deleteQuietly(tmpFile);
}
}
/**
* Parses multiple thumbnail configurations.
*
* @param args The configuration strings.
* @return A collection of parsed {@link ThumbnailConfig}s.
*
* @deprecated since 6.0, avoid thumbnail configuration in workflow processes, and use {@link com.day.cq.dam.api.renditions.RenditionMaker} service
*/
@Deprecated
public static Collection parseConfig(final String[] args) {
final Set configs = new HashSet();
for (final String arg : args) {
final ThumbnailConfig config = parseConfig(arg);
if (null != config) {
configs.add(config);
}
}
return configs;
}
/**
* Parse a thumbnail configuration in the following formats:
*
* [width:height:doCenter]
* or
* [width:height]
* or
* width:height:doCenter
* or
* width:height
*
* The configuration string must at least provide width and height. null
is returned if an invalid
* configuration string is encountered, namely non-numeric width/height or insufficient arguments.
*
* @param str The configuration string.
* @return A thumbnail config or null
if the configuration string is invalid.
*
* @deprecated since 6.0, avoid thumbnail configuration in workflow processes, and use {@link com.day.cq.dam.api.renditions.RenditionMaker} service
*/
@Deprecated
public static ThumbnailConfig parseConfig(String str) {
ThumbnailConfig config = null;
// remove any whitespace
str = str.trim();
// remove any square brackets
str = StringUtils.replaceEach(str, new String[]{"[", "]"}, new String[]{"", ""});
final String fragments[] = str.split(":");
// ensure sufficient arguments are present (at least width:height)
if (fragments.length >= 2) {
try {
final Integer width = Integer.valueOf(fragments[0]);
final Integer height = Integer.valueOf(fragments[1]);
boolean doCenter = false;
if (fragments.length > 2) {
doCenter = Boolean.valueOf(fragments[2]);
}
config = new ThumbnailConfigImpl(width, height, doCenter);
} catch (NumberFormatException e) {
log.warn("parseConfig: cannot parse, invalid width/height specified in config [{}]: ", str, e);
}
} else {
log.warn("parseConfig: cannot parse, insufficient arguments in config [{}].", str);
}
return config;
}
/**
* Returns thumbnail configurations for an array of given dimensions.
*
* @param dimensions The dimensions.
* @return A collection of thumbnail configurations.
*
* @deprecated since 6.0, avoid thumbnail configuration in workflow processes, and use {@link com.day.cq.dam.api.renditions.RenditionMaker} service
*/
@Deprecated
public static Collection getConfigs(final Collection dimensions) {
final Set configs = new HashSet();
for (final Integer[] dimension : dimensions) {
configs.add(new ThumbnailConfigImpl(dimension[0], dimension[1], false));
}
return configs;
}
private Layer createThumbnail(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;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy