KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > methodhead > shim > Thumbnailer


1 /*
2  * Copyright (C) 2006 Methodhead Software LLC. All rights reserved.
3  *
4  * This file is part of TransferCM.
5  *
6  * TransferCM is free software; you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation; either version 2 of the License, or (at your option) any later
9  * version.
10  *
11  * TransferCM is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
18  * Fifth Floor, Boston, MA 02110-1301 USA
19  */

20
21 package com.methodhead.shim;
22
23 import com.sun.image.codec.jpeg.JPEGEncodeParam;
24 import com.sun.image.codec.jpeg.JPEGCodec;
25 import com.sun.image.codec.jpeg.JPEGImageEncoder;
26 import java.io.BufferedOutputStream JavaDoc;
27 import java.awt.image.BufferedImage JavaDoc;
28 import java.awt.Image JavaDoc;
29 import java.awt.Container JavaDoc;
30 import java.awt.Graphics2D JavaDoc;
31 import java.awt.RenderingHints JavaDoc;
32 import java.awt.MediaTracker JavaDoc;
33 import java.awt.Toolkit JavaDoc;
34 import java.awt.Color JavaDoc;
35 import java.io.FileOutputStream JavaDoc;
36 import java.io.File JavaDoc;
37 import org.apache.log4j.Logger;
38 import org.apache.commons.lang.exception.ExceptionUtils;
39
40 /**
41  * Creates thumbnails of popular image formats.
42  */

43 public class Thumbnailer {
44
45   // constructors /////////////////////////////////////////////////////////////
46

47   // constants ////////////////////////////////////////////////////////////////
48

49   /**
50    * Maximum width of the thumbnail.
51    */

52   public static final int THUMB_HEIGHT = 50;
53
54   /**
55    * Maximum height of the thumbnail.
56    */

57   public static final int THUMB_WIDTH = 50;
58
59   /**
60    * Thumbnail quality in a range between 0.0 and 1.0.
61    */

62   public static final float THUMB_QUALITY = 1.0f;
63
64   // classes //////////////////////////////////////////////////////////////////
65

66   // methods //////////////////////////////////////////////////////////////////
67

68   /**
69    * Creates a thumbnail of <tt>src</tt> in the file specified by
70    * <tt>dest</tt>. The thumbnail is in JPEG format. It maintains the aspect
71    * ratio of the source image and is contrained by {@link #THUMB_WIDTH
72    * THUMB_WIDTH} and {@link #THUMB_HEIGHT THUMB_HEIGHT}.
73    */

74   public static void thumbnail(
75     File JavaDoc src,
76     File JavaDoc dest ) {
77
78     logger_.debug( "thumbnail(): Thumbnailing " + src + " to " + dest );
79
80     try {
81       if ( !src.exists() || !src.isFile() )
82         throw new ShimException(
83           "File does not exist or is not a file \"" + src + "\"" );
84
85       //
86
// load image
87
//
88
Image JavaDoc image = Toolkit.getDefaultToolkit().getImage( src.getAbsolutePath() );
89       MediaTracker JavaDoc mediaTracker = new MediaTracker JavaDoc( new Container JavaDoc() );
90       mediaTracker.addImage( image, 0 );
91       mediaTracker.waitForID(0);
92
93       //
94
// calculate width and height
95
//
96
int thumbWidth = THUMB_HEIGHT;
97       int thumbHeight = THUMB_WIDTH;
98       double thumbRatio = (double)thumbWidth / (double)thumbHeight;
99
100       int imageWidth = image.getWidth(null);
101       int imageHeight = image.getHeight(null);
102
103       //
104
// already smaller than the thumb?
105
//
106
if ( ( imageHeight <= THUMB_HEIGHT ) && ( imageWidth <= THUMB_WIDTH ) ) {
107         thumbHeight = imageHeight;
108         thumbWidth = imageWidth;
109       }
110
111       //
112
// scale the image to right size
113
//
114
else {
115         double imageRatio = (double)imageWidth / (double)imageHeight;
116
117         if (thumbRatio < imageRatio) {
118           thumbHeight = (int)(thumbWidth / imageRatio);
119         }
120         else {
121           thumbWidth = (int)(thumbHeight * imageRatio);
122         }
123       }
124
125       //
126
// make sure we're at least a pixel wide or tall
127
//
128
if ( thumbHeight == 0 )
129         thumbHeight = 1;
130
131       if ( thumbWidth == 0 )
132         thumbWidth = 1;
133
134       //
135
// draw original image to thumbnail image object and
136
// scale it to the new size on-the-fly
137
//
138
BufferedImage JavaDoc thumbImage = new BufferedImage JavaDoc(thumbWidth,
139         thumbHeight, BufferedImage.TYPE_INT_RGB);
140
141       Graphics2D JavaDoc graphics2D = thumbImage.createGraphics();
142       graphics2D.setRenderingHint(
143         RenderingHints.KEY_INTERPOLATION,
144         RenderingHints.VALUE_INTERPOLATION_BILINEAR);
145       graphics2D.setRenderingHint(
146         RenderingHints.KEY_ALPHA_INTERPOLATION,
147         RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
148       graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, Color.WHITE, null);
149
150       //
151
// save the thumbnail
152
//
153
BufferedOutputStream JavaDoc out = new BufferedOutputStream JavaDoc(new
154         FileOutputStream JavaDoc( dest ));
155       JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
156       JPEGEncodeParam param = encoder.
157         getDefaultJPEGEncodeParam(thumbImage);
158       param.setQuality(THUMB_QUALITY, false);
159       encoder.setJPEGEncodeParam(param);
160       encoder.encode(thumbImage);
161       out.close();
162     }
163
164     //
165
// these exceptions we know about
166
//
167
catch ( java.lang.InterruptedException JavaDoc e ) {
168       throw new ShimException( "Thumbnailing " + src + " to " + dest + ". " + ExceptionUtils.getStackTrace( e ) );
169     }
170     catch ( java.io.FileNotFoundException JavaDoc e ) {
171       throw new ShimException( "Thumbnailing " + src + " to " + dest + ". " + ExceptionUtils.getStackTrace( e ) );
172     }
173     catch ( java.io.IOException JavaDoc e ) {
174       throw new ShimException( "Thumbnailing " + src + " to " + dest + ". " + ExceptionUtils.getStackTrace( e ) );
175     }
176   }
177
178   /**
179    * Creates thumbnails for any JPG, GIF, and PNG file in <tt>src</tt> in
180    * <tt>dest</tt>. If a thumbnail already exists in <tt>dest</tt>, it is
181    * updated if the file in <tt>src</tt> is newer. The thumbnails are JPEG's,
182    * so ".jpg" is appended to the filename of each thumbnail. Some images
183    * cannot be processed properly and the resulting IllegalArgumentException is
184    * caught and logged, but otherwise ignored; no thumbnail file is created in
185    * this case.
186    */

187   public void syncDir(
188     File JavaDoc src,
189     File JavaDoc dest ) {
190
191     logger_.debug( "syncDir(): Syncing " + src + " to " + dest );
192
193     if ( !src.exists() || !src.isDirectory() )
194       throw new ShimException( "Invalid source directory \"" + src + "\"" );
195
196     if ( !dest.exists() || !dest.isDirectory() )
197       throw new ShimException( "Invalid dest directory \"" + dest + "\"" );
198
199     File JavaDoc[] files = src.listFiles();
200     for ( int i = 0; i < files.length; i++ ) {
201       String JavaDoc fileName = files[ i ].getName().toLowerCase();
202
203       if ( !fileName.endsWith( ".jpg" ) &&
204            !fileName.endsWith( ".jpeg" ) &&
205            !fileName.endsWith( ".png" ) &&
206            !fileName.endsWith( ".gif" ) )
207         continue;
208
209       File JavaDoc f = new File JavaDoc( dest, files[ i ].getName() + ".jpg" );
210
211       if ( f.exists() &&
212            f.isFile() &&
213            ( files[ i ].lastModified() < f.lastModified() ) )
214         continue;
215
216       try {
217         thumbnail( files[ i ], f );
218       }
219       catch ( IllegalArgumentException JavaDoc e ) {
220
221         //
222
// we know through practice that bad images cause
223
// IllegalArgumentExceptions; we ignore them
224
//
225
logger_.warn( "Couldn't thumbnail " + files[ i ] + ". " + e.getMessage() );
226       }
227     }
228   }
229
230   // properties ///////////////////////////////////////////////////////////////
231

232   // attributes ///////////////////////////////////////////////////////////////
233

234   //
235
// arbitrarily trying out a more aggresive logging effort
236
//
237
private static Logger logger_ = Logger.getLogger( Thumbnailer.class );
238 }
239
Popular Tags