View Javadoc

1   package org.varienaja.util.coverart;
2   
3   import java.awt.Dimension;
4   import java.awt.Graphics2D;
5   import java.awt.GraphicsEnvironment;
6   import java.awt.Image;
7   import java.awt.RenderingHints;
8   import java.awt.image.BufferedImage;
9   import java.io.BufferedOutputStream;
10  import java.io.FileInputStream;
11  import java.io.FileNotFoundException;
12  import java.io.FileOutputStream;
13  import java.io.IOException;
14  import java.io.InputStream;
15  
16  import javax.imageio.ImageIO;
17  
18  import org.apache.log4j.Logger;
19  
20  import com.sun.image.codec.jpeg.JPEGCodec;
21  import com.sun.image.codec.jpeg.JPEGEncodeParam;
22  import com.sun.image.codec.jpeg.JPEGImageEncoder;
23  
24  /**
25   * This class provides functions for scaling square jpeg-images to new sizes. 
26   * @author Varienaja
27   */
28  public class ImageScaler {
29  	
30  	/**
31  	 * Scales a source-jpeg to a new jpeg. The new jpeg will be compressed with
32  	 * a quality of 90%.
33  	 * @param input The source jpeg to use
34  	 * @param dest The filename of the target jpeg (will be generated)
35  	 * @param newSize The new size of the image (will be used for both x and y)
36  	 * @return true, if the resize operation succeeded, false otherwise
37  	 */
38  	public static boolean scale(InputStream input, String dest, int newSize) {
39  		BufferedImage image = null;
40  		try {
41  			image = scale(input,newSize);
42  		    //Save thumbnail image to destination
43  		    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
44  		    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
45  		    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
46  		    int quality = 90;
47  		    param.setQuality((float)quality / 100.0f, false);
48  		    encoder.setJPEGEncodeParam(param);
49  		    encoder.encode(image);
50  		    out.close(); 
51  		    return true;
52  		} catch (Exception e) {
53  			return false;
54  		}
55  	}
56  	
57  	public static boolean scale(String source, String dest, int newSize) throws FileNotFoundException {
58  		FileInputStream src = new FileInputStream(source);
59  		boolean result = scale(src,dest,newSize);
60  		try {
61  			src.close();
62  		} catch (IOException e) {
63  			//ignore.
64  		}
65  		return result;
66  	}
67  
68  	/**
69  	 * Scales a source-jpeg to a new image
70  	 * @param input The source jpeg to use
71  	 * @param newSize The new size of the image (will be used for both x and y)
72  	 * @return The image as a BufferedImage
73  	 */
74  	public static BufferedImage scale(InputStream input, int newSize) throws Exception {
75  	    try {
76  	    	BufferedImage image = ImageIO.read(input);
77  	        return scaleInternal(image,newSize);
78  	    } catch (Exception e) {
79  	    	return null;
80  	    }
81  	}
82  	
83  	/**
84  	 * Scales a source-image to a new image
85  	 * @param image The image to use as source
86  	 * @param newSize The new size of the image (will be used for both x and y)
87  	 * @return The image as a BufferedImage
88  	 */
89  	public static BufferedImage scale(Image image, int newSize) throws Exception {
90  		try {
91  			return scaleInternal(image,newSize);
92  		} catch (Exception e) {
93  			return null;
94  		}
95  	}
96  
97  	/**
98  	 * Scales a source-image to a new image
99  	 * @param image The image to use as source
100 	 * @param newSize The new size of the image (will be used for both x and y)
101 	 * @return The image as a BufferedImage
102 	 */
103 	private static BufferedImage scaleInternal(Image image, int newSize) throws Exception {
104 		Dimension resized = calculateNewDimension(image.getWidth(null), image.getHeight(null), newSize);
105 		    
106 		//Draw original image to thumbnail image object and scale it to the new size on-the-fly
107 		BufferedImage thumbImage = new BufferedImage(resized.width,resized.height,BufferedImage.TYPE_INT_RGB);
108 		Graphics2D graphics2D = thumbImage.createGraphics();
109 		graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);
110 		graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON );
111 		graphics2D.drawImage(image, 0, 0, resized.width, resized.height, null);
112 		graphics2D.dispose();
113 		return thumbImage;
114 	}
115 	
116 	/**
117 	 * Calculates a new dimension for an object.
118 	 * @param width The width of an object.
119 	 * @param height The height of an object.
120 	 * @param newSize The maximum size of an object (both width and height)
121 	 * @return The new Dimension of the image, where width or height are exactly newSize
122 	 * and the aspect-ratio is unchanged.
123 	 */
124 	public static Dimension calculateNewDimension(int width, int height, int newSize) {
125 		//Determine thumbnail size from newSize
126 		int thumbWidth = newSize;
127 		int thumbHeight = newSize;
128 		double thumbRatio = (double)thumbWidth / (double)thumbHeight;
129 		int imageWidth = width;
130 		int imageHeight = height;
131 		double imageRatio = (double)imageWidth / (double)imageHeight;
132 		if (thumbRatio < imageRatio) {
133 		  thumbHeight = (int)(thumbWidth / imageRatio);
134 		} else {
135 		  thumbWidth = (int)(thumbHeight * imageRatio);
136 		}
137 		return new Dimension(thumbWidth, thumbHeight);
138 	}
139 }