com.celements.photo.plugin.cmd.ComputeImageCommand.java Source code

Java tutorial

Introduction

Here is the source code for com.celements.photo.plugin.cmd.ComputeImageCommand.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.celements.photo.plugin.cmd;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.celements.photo.container.ImageDimensions;
import com.celements.photo.image.GenerateThumbnail;
import com.celements.photo.image.ICropImage;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.web.Utils;

public class ComputeImageCommand {

    private static final Log LOGGER = LogFactory.getFactory().getInstance(ComputeImageCommand.class);

    private ImageCacheCommand imgCacheCmd;

    public XWikiAttachment computeImage(XWikiAttachment attachment, XWikiContext context,
            XWikiAttachment attachmentClone, String sheight, String swidth, String copyright, String watermark,
            Color defaultBg, String defaultBgString) {
        // crop params
        int cropX = parseIntWithDefault(context.getRequest().get("cropX"), -1);
        int cropY = parseIntWithDefault(context.getRequest().get("cropY"), -1);
        int cropW = parseIntWithDefault(context.getRequest().get("cropW"), -1);
        int cropH = parseIntWithDefault(context.getRequest().get("cropH"), -1);
        boolean needsCropping = needsCropping(cropX, cropY, cropW, cropH);
        LOGGER.debug("Crop needed: " + needsCropping + " -> " + cropX + ":" + cropY + " " + cropW + "x" + cropH);
        // resize params
        if ((defaultBgString != null) && defaultBgString.matches("[0-9A-Fa-f]{6}")) {
            int r = Integer.parseInt(defaultBgString.substring(1, 3), 16);
            int g = Integer.parseInt(defaultBgString.substring(3, 5), 16);
            int b = Integer.parseInt(defaultBgString.substring(5), 16);
            defaultBg = new Color(r, g, b);
        }
        int height = parseIntWithDefault(sheight, 0);
        int width = parseIntWithDefault(swidth, 0);
        try {
            attachmentClone = (XWikiAttachment) attachment.clone();
            //      mLogger.debug("dimension: target width=" + width + "; target height=" + height
            //          + "; resized width=" + dimension.getWidth() + "; resized height="
            //          + dimension.getHeight());
            String key = getImageCacheCmd().getCacheKey(attachmentClone, new ImageDimensions(width, height),
                    copyright, watermark, cropX, cropY, cropW, cropH);
            LOGGER.debug("attachment key: '" + key + "'");
            InputStream data = getImageCacheCmd().getImageForKey(key);
            if (data != null) {
                LOGGER.info("Found image in Cache.");
                attachmentClone.setContent(data);
            } else {
                LOGGER.info("No cached image.");
                GenerateThumbnail thumbGen = new GenerateThumbnail();
                InputStream in = attachmentClone.getContentInputStream(context);
                DecodeImageCommand decodeImageCommand = new DecodeImageCommand();
                BufferedImage img = decodeImageCommand.readImage(attachmentClone, context);
                in.close();
                if (needsCropping) {
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    ICropImage cropComp = Utils.getComponent(ICropImage.class);
                    cropComp.crop(img, cropX, cropY, cropW, cropH, attachmentClone.getMimeType(context), out);
                    attachmentClone
                            .setContent(new ByteArrayInputStream(((ByteArrayOutputStream) out).toByteArray()));
                    in = attachmentClone.getContentInputStream(context);
                    img = decodeImageCommand.readImage(attachmentClone, context);
                    in.close();
                }
                if ((height > 0) || (width > 0)) {
                    ImageDimensions dimension = thumbGen.getThumbnailDimensions(img, width, height);
                    byte[] thumbImageData = getThumbAttachment(img, dimension, thumbGen,
                            attachmentClone.getMimeType(context), watermark, copyright, defaultBg);
                    attachmentClone.setContent(new ByteArrayInputStream(thumbImageData));
                }
                getImageCacheCmd().addToCache(key, attachmentClone);
            }
        } catch (Exception exp) {
            LOGGER.error("Error, could not resize / cache image", exp);
            attachmentClone = attachment;
        }
        return attachmentClone;
    }

    private boolean needsCropping(int cropX, int cropY, int cropW, int cropH) {
        return (cropX >= 0) && (cropY >= 0) && (cropW > 0) && (cropH > 0);
    }

    int parseIntWithDefault(String stringValue, int defValue) {
        int parsedValue = defValue;
        if ((stringValue != null) && (stringValue.length() > 0)) {
            try {
                parsedValue = Integer.parseInt(stringValue);
            } catch (NumberFormatException numExp) {
                LOGGER.debug("Failed to parse height [" + stringValue + "].", numExp);
            }
        }
        return parsedValue;
    }

    void injectImageCacheCmd(ImageCacheCommand mockImgCacheCmd) {
        imgCacheCmd = mockImgCacheCmd;
    }

    ImageCacheCommand getImageCacheCmd() {
        if (imgCacheCmd == null) {
            imgCacheCmd = new ImageCacheCommand();
        }
        return imgCacheCmd;
    }

    public void flushCache() {
        if (imgCacheCmd != null) {
            imgCacheCmd.flushCache();
            imgCacheCmd = null;
        }
    }

    private byte[] getThumbAttachment(BufferedImage img, ImageDimensions dim, GenerateThumbnail thumbGen,
            String mimeType, String watermark, String copyright, Color defaultBg) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        thumbGen.createThumbnail(img, out, dim, watermark, copyright, mimeType, defaultBg);
        return out.toByteArray();
    }

}