package org.geoserver.rest.upload; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.AffineTransformOp; import java.util.logging.Logger; import java.util.logging.Level; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import javax.imageio.stream.FileImageOutputStream; import javax.imageio.stream.ImageOutputStream; /** * FileStorage implementation for storing uploaded images in multiple sizes. * * @author David Winslow <dwinslow@opengeo.org> */ public class ThumbnailStorage implements FileStorage { private static final Dimension THUMB_SIZE = new Dimension( 100, 100); private static final Dimension FULL_SIZE = new Dimension(1000, 1000); // private Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.rest.upload"); public List handleUpload( String contentType, File content, UniqueIDGenerator namer, File uploadDirectory ) throws IOException { String originalName = null; ImageWriter format = null; BufferedImage image = null; originalName = ""; format = findWriter(contentType); image = ImageIO.read(content); double thumbScale = getDesiredSize(image.getWidth(), image.getHeight(), THUMB_SIZE); double fullScale = getDesiredSize(image.getWidth(), image.getHeight(), FULL_SIZE); String thumbName = namer.generate("thumb_" + originalName); String fullName = namer.generate("full_" + originalName); writeResized(image, thumbScale, format, thumbName, uploadDirectory); writeResized(image, fullScale, format, fullName, uploadDirectory); List l = new ArrayList(); l.add(thumbName); l.add(fullName); return l; } private double getDesiredSize(int width, int height, Dimension max) { return getDesiredSize(new Dimension(width, height), max); } private double getDesiredSize(Dimension original, Dimension max) { if (original.getWidth() <= max.getWidth() && original.getHeight() <= max.getHeight()) { return 1.0; } double newWidth = original.getWidth() * (max.getHeight() / original.getHeight()); if (newWidth > max.getWidth()){ return max.getHeight() / original.getHeight(); } else { return max.getWidth() / original.getWidth(); } } private void writeResized(BufferedImage image, double scale, ImageWriter format, String name, File root) throws IOException { BufferedImage scaledImage = null; if (Math.abs(scale - 1.0) > 0.001) { AffineTransform xform = AffineTransform.getScaleInstance(scale, scale); AffineTransformOp op = new AffineTransformOp(xform, AffineTransformOp.TYPE_BILINEAR); Rectangle2D dim = op.getBounds2D(image); scaledImage = new BufferedImage( (int)dim.getMaxX(), (int)dim.getMaxY(), image.getType() ); scaledImage = op.filter(image, scaledImage); } else { scaledImage = image; } File f = new File(root, name); ImageOutputStream out = new FileImageOutputStream(f); format.setOutput(out); format.write(scaledImage); out.flush(); out.close(); } private ImageWriter findWriter(String contentType) { Iterator<ImageWriter> it = ImageIO.getImageWritersByMIMEType(contentType); if (it.hasNext()) return it.next(); return null; } }