Java tutorial
/* * 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(); } }