/* * eXist Image Module Extension * Copyright (C) 2006-09 Adam Retter <adam.retter@devon.gov.uk> * www.adamretter.co.uk * * This program 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 * of the License, or (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ */ package org.exist.xquery.modules.image; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import javax.imageio.ImageIO; import org.exist.util.Base64Decoder; import org.exist.xquery.AbstractInternalModule; import org.exist.xquery.FunctionDef; import org.exist.xquery.XPathException; import org.exist.xquery.value.Base64Binary; /** * eXist Image Module Extension * * An extension module for the eXist Native XML Database that allows operations * on images stored in the eXist database. * * @author Adam Retter <adam.retter@devon.gov.uk> * @author ljo * @serial 2006-03-10 * @version 1.0 * * @see org.exist.xquery.AbstractInternalModule#AbstractInternalModule(org.exist.xquery.FunctionDef[]) */ public class ImageModule extends AbstractInternalModule { /* * TODO: metadata extraction from images, especially JPEG's */ public final static String NAMESPACE_URI = "http://exist-db.org/xquery/image"; public final static String PREFIX = "image"; public final static String INCLUSION_DATE = "2006-03-13"; public final static String RELEASED_IN_VERSION = "eXist-1.2"; private final static FunctionDef[] functions = { new FunctionDef(GetWidthFunction.signature, GetWidthFunction.class), new FunctionDef(GetHeightFunction.signature, GetHeightFunction.class), new FunctionDef(GetMetadataFunction.signature, GetMetadataFunction.class), new FunctionDef(ScaleFunction.signature, ScaleFunction.class), new FunctionDef(GetThumbnailsFunction.signature, GetThumbnailsFunction.class), new FunctionDef(CropFunction.signature, CropFunction.class) }; public ImageModule() { super(functions); } public String getNamespaceURI() { return NAMESPACE_URI; } public String getDefaultPrefix() { return PREFIX; } public String getDescription() { return "A module for performing operations on Images stored in the eXist db"; } public String getReleaseVersion() { return RELEASED_IN_VERSION; } /** * Get's an the raw binary data from base64 binary encoded image data * * @param imgBase64Data The base64 encoded image data * * @return The raw binary data */ protected static byte[] getImageData(Base64Binary imgBase64Data) throws XPathException { //decode the base64 image data Base64Decoder dec = new Base64Decoder(); dec.translate(imgBase64Data.getStringValue()); //return the raw binary data return dec.getByteArray(); } /** * Get's an Image object from base64 binary encoded image data * * @param imgBase64Data The base64 encoded image data * * @return An Image object */ protected static Image getImage(Base64Binary imgBase64Data) throws IOException, XPathException { //Create an Image object from the byte array return ImageIO.read(new ByteArrayInputStream(getImageData(imgBase64Data))); } /** * @author Rafael Troilo (rtroilo@gmail.com) */ protected static BufferedImage createThumb(Image image, int height, int width) { int thumbWidth = 0; int thumbHeight = 0; double scaleFactor = 0.0; BufferedImage thumbImage = null; Graphics2D graphics2D = null; int imageHeight = image.getHeight(null); int imageWidth = image.getWidth(null); if (imageHeight >= imageWidth) { scaleFactor = (double) height / (double) imageHeight; thumbWidth = (int) (imageWidth * scaleFactor); thumbHeight = height; if (thumbWidth > width) { // thumbwidth is greater than // maxThumbWidth, so we have to scale // again scaleFactor = (double) width / (double) thumbWidth; thumbHeight = (int) (thumbHeight * scaleFactor); thumbWidth = width; } } else { scaleFactor = (double) width / (double) imageWidth; thumbHeight = (int) (imageHeight * scaleFactor); thumbWidth = width; if (thumbHeight > height) { // thumbHeight is greater than // maxThumbHeight, so we have to scale // again scaleFactor = (double) height / (double) thumbHeight; thumbWidth = (int) (thumbWidth * scaleFactor); thumbHeight = height; } } thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); graphics2D = thumbImage.createGraphics(); graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null); return thumbImage; } }