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

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