/* * 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.image; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Iterator; import java.util.List; import com.celements.photo.container.ImageDimensions; import com.celements.photo.container.ImageLibStrings; import com.celements.photo.utilities.AddAttachmentToDoc; import com.celements.photo.utilities.BaseObjectHandler; import com.celements.photo.utilities.FileNameManipulator; import com.celements.photo.utilities.ZipAttachmentChanges; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.doc.XWikiAttachment; import com.xpn.xwiki.doc.XWikiDocument; import com.xpn.xwiki.objects.BaseObject; /** * Provides functions to access and handle thumbnails. */ public class Thumbnail { /** * Returns the URL to the thumbnail of a certain image in the specified * size. If the thumbnail does not exist it is created. * * @param doc XWikiDocument of the album. * @param image Name of the image * @param width Desired width for the thumb * @param height Desired height for the thumb * @param imageMethods To be able to get the original image from its zip * archive. * @param context XWikiContext * @return The download URL for the thumb * @throws XWikiException * @throws IOException */ public String getUrl(XWikiDocument doc, String id, int width, int height, XWikiContext context) throws XWikiException, IOException { String album = doc.getName(); ZipAttachmentChanges zipAttChanges = new ZipAttachmentChanges(); GenerateThumbnail thumbGenerator = new GenerateThumbnail(); XWikiAttachment zipAttachment = zipAttChanges.getContainingZip(doc, id, context); ImageDimensions imgSize = getThumbnailDimensions(doc, id, width, height, thumbGenerator, context); XWikiDocument celeMetaDoc = context.getWiki().getDocument( ImageLibStrings.getPhotoSpace(doc), album + ImageLibStrings.DOCUMENT_SEPARATOR_IMAGE + id, context); if(imgSize.isEmpty()){ String dir = (new BaseObjectHandler()).getImageString(celeMetaDoc, ImageLibStrings.PHOTO_IMAGE_ZIPDIRECTORY); String image = (new BaseObjectHandler()).getImageString(celeMetaDoc, ImageLibStrings.PHOTO_IMAGE_FILENAME); try{ BufferedImage original = thumbGenerator.decodeInputStream(zipAttChanges.getFromZip(zipAttachment, dir + image, context)); imgSize = thumbGenerator.getImageDimensions(original); writeImageDimensionsToMetadata(doc, id, imgSize, context); imgSize = thumbGenerator.getThumbnailDimensions(original, width, height); }catch(Exception e){ throw new IOException(image + "^^" + id); } } String thumbImageName = (new FileNameManipulator()).addSizeToFileName(id, (int)imgSize.getWidth(), (int)imgSize.getHeight()); XWikiAttachment thumbnail = celeMetaDoc.getAttachment(thumbImageName); if((thumbnail == null) || (thumbnail.getDate().before(zipAttachment.getDate()))){ deleteOutdated(thumbnail, celeMetaDoc, context); String dir = (new BaseObjectHandler()).getImageString(celeMetaDoc, ImageLibStrings.PHOTO_IMAGE_ZIPDIRECTORY); String filename = (new BaseObjectHandler()).getImageString(celeMetaDoc, ImageLibStrings.PHOTO_IMAGE_FILENAME); BufferedImage original = thumbGenerator.decodeInputStream(zipAttChanges.getFromZip(zipAttachment, dir + filename, context)); ByteArrayOutputStream out = new ByteArrayOutputStream(); thumbGenerator.createThumbnail(original, out, width, height, getWatermark(doc, context), getCopyright(doc, context), zipAttachment.getMimeType(context), null); thumbnail = (new AddAttachmentToDoc()).addAtachment(celeMetaDoc, out, thumbImageName, context); } String imageURL = celeMetaDoc.getAttachmentURL(thumbnail.getFilename(), ImageLibStrings.XWIKI_URL_DOWNLOAD, context); return imageURL; } private void deleteOutdated(XWikiAttachment thumbnail, XWikiDocument celeMetaDoc, XWikiContext context) throws XWikiException { if(thumbnail != null){ celeMetaDoc.deleteAttachment(thumbnail, context); } } /** * Get the String to add to thumbnails as a watermark. * * @param doc XWikiDocument of the album. * @param context XWikiContext * @return String to add to the image as a watermark. * @throws XWikiException */ private String getWatermark(XWikiDocument doc, XWikiContext context) throws XWikiException { return getObjctDescription(doc, ImageLibStrings.PHOTO_ALBUM_WATERMARK); } /** * Get the String to add to thumbnails as copyright information. * * @param doc XWikiDocument of the album. * @param context XWikiContext * @return String to add to the image as copyright information. * @throws XWikiException */ private String getCopyright(XWikiDocument doc, XWikiContext context) throws XWikiException { return getObjctDescription(doc, ImageLibStrings.PHOTO_ALBUM_COPYRIGHT); } /** * Gets the thumbnail's dimensions, using the image dimension information * saved in the celements photo plugin metadata. * * @param doc XWikiDocument of the album. * @param image Name of the image. * @param width Maximum allowed width. * @param height Maximum allowed height. * @param context XWikiContext * @return ImageDimensions object containing the dimensions of the thumbnail. * @throws XWikiException */ private ImageDimensions getThumbnailDimensions(XWikiDocument doc, String id, int width, int height, GenerateThumbnail thumbGenerator, XWikiContext context) throws XWikiException{ XWikiDocument imageDoc = context.getWiki().getDocument(ImageLibStrings.getPhotoSpace(doc), doc.getName() + ImageLibStrings.DOCUMENT_SEPARATOR_IMAGE + id, context); BaseObjectHandler handler = new BaseObjectHandler(); int imgWidth = handler.getImageInteger(imageDoc, ImageLibStrings.PHOTO_IMAGE_WIDTH); int imgHeight = handler.getImageInteger(imageDoc, ImageLibStrings.PHOTO_IMAGE_HEIGHT); return thumbGenerator.getThumbnailDimensions(imgWidth, imgHeight, width, height); } /** * Caches the real image dimensions to the celements photo plugin metadata. * * @param doc XWikiDocument of the album. * @param image Name of the image. * @param imgDim True dimensions of the image. * @param context XWikiContext * @throws XWikiException */ private void writeImageDimensionsToMetadata(XWikiDocument doc, String id, ImageDimensions imgDim, XWikiContext context) throws XWikiException{ XWikiDocument imageDoc = context.getWiki().getDocument(ImageLibStrings.getPhotoSpace(doc), doc.getName() + ImageLibStrings.DOCUMENT_SEPARATOR_IMAGE + id, context); BaseObject metainfoObj = imageDoc.getObject(ImageLibStrings.PHOTO_IMAGE_CLASS); metainfoObj.setIntValue(ImageLibStrings.PHOTO_IMAGE_WIDTH, (int)imgDim.getWidth()); metainfoObj.setIntValue(ImageLibStrings.PHOTO_IMAGE_HEIGHT, (int)imgDim.getHeight()); context.getWiki().saveDocument(imageDoc, context); } /** * Gets the specified Object's description (value) from a document. If the * tag does not exist it is added and initialised to the given value. * * @param doc The XWikiDocument of the album. * @param tagName The name of the tag to fetch. * @return The description of the specified tag. * @throws XWikiException */ private String getObjctDescription(XWikiDocument doc, String tagName) throws XWikiException { if(!doc.isNew()){ List<BaseObject> tags = doc.getObjects(ImageLibStrings.PHOTO_ALBUM_CLASS); for (Iterator<BaseObject> iter = tags.iterator(); iter.hasNext();) { BaseObject tag = iter.next(); if((tag != null)){ return tag.getStringValue(tagName); } } } return ""; } }