package com.rectang.xsm.widget; import com.rectang.xsm.doc.SupportedOption; import com.rectang.xsm.io.PublishedFile; import com.rectang.xsm.io.XSMDocument; import com.rectang.xsm.util.FileUtils; import java.util.*; import java.awt.image.BufferedImage; import java.awt.Graphics2D; import java.io.*; import javax.imageio.*; import org.jdom.Element; public class PreviewedImage extends Image implements Serializable { public static final SupportedOption KEEP_ORIG = new SupportedOption( "KEEP_ORIG", "Keep the origional (full sized) images? [Old images should be re-uploaded]", true ); public static final SupportedOption THUMB_SIZE = new SupportedOption( "THUMB_SIZE", "The maximum size in pixels for image thumbnails [Old images should be re-uploaded]", 160 ); public static final SupportedOption PREVIEW_SIZE = new SupportedOption( "PREVIEW_SIZE", "The maximum size in pixels for image previews [Old images should be re-uploaded]", 800 ); private Vector options; public PreviewedImage( java.lang.String name ) { super( name ); options = new Vector(); options.add( KEEP_ORIG ); options.add( THUMB_SIZE ); options.add( PREVIEW_SIZE ); } protected java.lang.String getViewURL( Element node ) { return getPath( FileUtils.getImageThumbnailName( node.getValue() ) ); } public void publish( Element node, StringBuffer s ) { if ( node.getValue() == null || node.getValue().equals( "" ) ) { s.append( "(no image)\n" ); } else { s.append( "<a href=\"" + getSite().getPrefixUrl() ); s.append( getPath( FileUtils.getImagePreviewName( node.getValue() ) ) + "\"><img src=\"" ); s.append( getSite().getPrefixUrl() ); s.append( getPath( FileUtils.getImageThumbnailName( node.getValue() ) ) + "\" border=\"0\"/></a>\n" ); } } public void destroy( Element node ) { java.lang.String imageName = node.getText(); if ( imageName == null || imageName.equals( "" ) ) { return; } PublishedFile file = (getSite().getPublishedDoc( getPath( imageName ) )); if ( file.exists() ) { file.delete(); } file = (getSite().getPublishedDoc( getPath( FileUtils.getImagePreviewName( imageName ) ) )); if ( file.exists() ) { file.delete(); } file = (getSite().getPublishedDoc( getPath( FileUtils.getImageThumbnailName( imageName ) ) )); if ( file.exists() ) { file.delete(); } } private static BufferedImage thumbnail( BufferedImage in, int max ) { int width = in.getWidth(); int height = in.getHeight(); int newWidth, newHeight; if ( width <= max && height <= max ) { newWidth = width; newHeight = height; } else { double dw = (double) max / width; double dh = (double) max / height; double mind = Math.min( dw, dh ); newWidth = (int) (((double) width) * mind); newHeight = (int) (((double) height) * mind); } BufferedImage out = new BufferedImage( newWidth, newHeight, BufferedImage.TYPE_INT_RGB ); Graphics2D g2d = out.createGraphics(); g2d.drawImage( in.getScaledInstance( newWidth, newHeight, java.awt.Image.SCALE_SMOOTH ), 0, 0, null ); g2d.dispose(); return out; } protected void clearOldFiles( Element node ) { java.lang.String oldName = node.getText(); if ( oldName != null && !oldName.equals( "" ) ) { PublishedFile oldFile = getSite().getPublishedDoc( getPath( oldName ) ); if ( oldFile.exists() ) { oldFile.delete(); } oldFile = getSite().getPublishedDoc( getPath( FileUtils.getImagePreviewName( oldName ) ) ); if ( oldFile.exists() ) { oldFile.delete(); } oldFile = getSite().getPublishedDoc( getPath( FileUtils.getImageThumbnailName( oldName ) ) ); if ( oldFile.exists() ) { oldFile.delete(); } node.setText( "" ); } super.clearOldFiles( node ); } protected void processFile( java.lang.String fileName, java.io.File in, PublishedFile pub ) throws XSMDocument.GenerationException { boolean keep_orig = KEEP_ORIG.getBoolean( getDoc() ); int thumb_size = THUMB_SIZE.getInteger( getDoc() ); int preview_size = PREVIEW_SIZE.getInteger( getDoc() ); try { BufferedImage full = ImageIO.read( new FileInputStream( in ) ); PublishedFile preview = getSite().getPublishedDoc( getPath( FileUtils.getImagePreviewName( fileName ) ) ); BufferedImage capped = thumbnail( full, preview_size ); preview.mkparentdirs(); /* needed as getOutputStream does not mkdir */ OutputStream tmp = preview.getOutputStream(); ImageIO.write( capped, "JPG", tmp ); tmp.close(); PublishedFile thumb = getSite().getPublishedDoc( getPath( FileUtils.getImageThumbnailName( fileName ) ) ); tmp = thumb.getOutputStream(); ImageIO.write( thumbnail( capped, thumb_size ), "JPG", tmp ); tmp.close(); if ( keep_orig ) { pub.uploadFile( in ); } } catch ( IOException e ) { throw new XSMDocument.GenerationException( "Error generating image thumbnails: " + e.getMessage() ); } } public List getSupportedOptions() { return options; } }