001: /*
002: * Created on Dec 8, 2004
003: */
004: package com.openedit.modules.image;
005:
006: import java.awt.Dimension;
007: import java.awt.Graphics2D;
008: import java.awt.RenderingHints;
009: import java.awt.image.BufferedImage;
010: import java.io.File;
011: import java.io.FileNotFoundException;
012: import java.io.IOException;
013:
014: import javax.imageio.ImageIO;
015:
016: import org.apache.commons.logging.Log;
017: import org.apache.commons.logging.LogFactory;
018:
019: import com.openedit.OpenEditException;
020: import com.openedit.page.manage.MimeTypeMap;
021: import com.openedit.util.PathUtilities;
022:
023: /**
024: * Resizes JPEG images.
025: *
026: * @author dbrown
027: *
028: */
029: public class ImageResizer implements ImageConverter {
030: private static final Log log = LogFactory
031: .getLog(ImageResizer.class);
032: protected MimeTypeMap fieldMimeTypeMap;
033:
034: /* (non-Javadoc)
035: * @see com.openedit.modules.image.ImageConverter#canResize(java.lang.String)
036: */
037: public boolean canConvert(String inPath) {
038: String mime = getMimeTypeMap().getMimeType(
039: PathUtilities.extractPageType(inPath));
040: if (mime.startsWith("image")) {
041: return true;
042: }
043: return true;
044: }
045:
046: public boolean canResize(String inPath) {
047: return canConvert(inPath);
048: }
049:
050: /**
051: * TODO - This main method is just for testing
052: * @param args
053: */
054: public static void main(String[] args) {
055: try {
056: if (args.length < 2) {
057: log.error("Usage: dir|file in out");
058: return;
059: }
060: ImageResizer resizer = new ImageResizer();
061: /* int numImages = resizer.resizeImagesInDirectory(
062: new File("/home/dbrown/workspace/openedit-cart/webapp/photos"),
063: new File("/home/dbrown/workspace/openedit-cart/webapp/photos-scaled"),
064: true );
065:
066: */
067: ConvertInstructions inStructions = new ConvertInstructions();
068: if ("dir".equals(args[0])) {
069: int numImages = resizer.resizeImagesInDirectory(
070: new File(args[1]), new File(args[2]),
071: inStructions, true);
072: log.info(numImages + " image(s) scaled");
073:
074: } else {
075: File in = new File(args[1]);
076: File out = new File(args[2]);
077: log.info("Converting " + in.getAbsolutePath() + " to "
078: + out.getPath());
079:
080: resizer.resizeImage(in, out, inStructions);
081: }
082:
083: } catch (Exception e) {
084: System.err.println("Fatal exception: " + e);
085: e.printStackTrace();
086: }
087: }
088:
089: public ImageResizer() {
090: }
091:
092: /**
093: * Resizes all JPEG images (files with .jpg or .jpeg extension) in
094: * the specified directory, unless they already exist in the target
095: * directory.
096: *
097: * @param inInDirectory input directory
098: * @param inOutDirectory output directory, will be created if it does not exist
099: * @param inRecurse true if this is to recurse through directories
100: * @return number of files resized
101: * @throws IOException
102: */
103: public int resizeImagesInDirectory(File inInDirectory,
104: File inOutDirectory, ConvertInstructions inStructions,
105: boolean inRecurse) throws Exception {
106:
107: // validate input arguments
108: if (!inInDirectory.exists()) {
109: throw new FileNotFoundException(inInDirectory
110: + " does not exist");
111: }
112: if (!inOutDirectory.exists() && !inOutDirectory.mkdirs()) {
113: throw new FileNotFoundException(inOutDirectory
114: + " does not exist and cannot be created");
115: }
116: if (!inInDirectory.isDirectory()) {
117: throw new IllegalArgumentException(inInDirectory
118: + " is not a directory");
119: }
120: if (!inOutDirectory.isDirectory()) {
121: throw new IllegalArgumentException(inOutDirectory
122: + " is not a directory");
123: }
124: if (inInDirectory.equals(inOutDirectory)) {
125: throw new IllegalArgumentException(
126: "directory arguments are the same");
127: }
128:
129: // resize all images with a .jpg or .jpeg extension
130: int numImagesResized = 0;
131: File[] inputFiles = inInDirectory.listFiles();
132: for (int n = 0; n < inputFiles.length; n++) {
133: File inputFile = inputFiles[n];
134: String filename = inputFile.getName();
135: if (inputFile.isDirectory()) {
136: if (inRecurse) {
137: File outputDir = new File(inOutDirectory, filename);
138: outputDir.mkdir();
139: numImagesResized += resizeImagesInDirectory(
140: inputFile, outputDir, inStructions,
141: inRecurse);
142: }
143: } else {
144: if (filename.toLowerCase().endsWith("jpg")
145: || filename.toLowerCase().endsWith("jpeg")) {
146: File outputFile = new File(inOutDirectory, filename);
147: if (outputFile.exists()) {
148: log.info("Skipping resizing " + filename);
149: } else {
150: try {
151: resizeImage(inputFile, outputFile,
152: inStructions);
153: numImagesResized++;
154: } catch (IOException e) {
155: log.error("Image " + inputFile
156: + " could not be resized");
157: log.error(e);
158: }
159: }
160: }
161: }
162: }
163:
164: return numImagesResized;
165: }
166:
167: /* (non-Javadoc)
168: * @see com.openedit.modules.image.ImageConverter#resizeImage(java.io.File, java.io.File)
169: */
170: public boolean resizeImage(File inInImageFile, File inOutImageFile,
171: ConvertInstructions inStructions) throws Exception {
172: BufferedImage origImage = ImageIO.read(inInImageFile);
173: if (origImage == null) {
174: throw new IllegalArgumentException(
175: "Input file is not valid "
176: + inInImageFile.getPath());
177: }
178: Dimension scaledSize = getScaledSize(origImage, inStructions);
179: BufferedImage scaledImage = new BufferedImage(scaledSize.width,
180: scaledSize.height, BufferedImage.TYPE_INT_RGB);
181: Graphics2D scaledGraphics = scaledImage.createGraphics();
182: scaledGraphics.setRenderingHint(
183: RenderingHints.KEY_INTERPOLATION,
184: RenderingHints.VALUE_INTERPOLATION_BICUBIC);
185: scaledGraphics.drawImage(origImage, 0, 0, scaledSize.width,
186: scaledSize.height, null);
187: inOutImageFile.getParentFile().mkdirs();
188: ImageIO.write(scaledImage, "jpeg", inOutImageFile);
189: log.info("Resize complete " + inInImageFile.getPath());
190: return true;
191: }
192:
193: /* (non-Javadoc)
194: * @see com.openedit.modules.image.ImageConverter#convert(java.io.File, java.io.File)
195: */
196: public boolean convert(File inIn, File inOut,
197: ConvertInstructions inStructions) throws OpenEditException {
198: throw new OpenEditException("Method not implemented");
199: }
200:
201: protected Dimension getScaledSize(BufferedImage inOrigImage,
202: ConvertInstructions inStructions) {
203: Dimension maxSize = inStructions.getMaxScaledSize();
204: double heightScale = (double) maxSize.height
205: / (double) inOrigImage.getHeight();
206: heightScale = Math.min(heightScale, 1.0);
207: double widthScale = (double) maxSize.width
208: / (double) inOrigImage.getWidth();
209: widthScale = Math.min(widthScale, 1.0);
210: double scale = Math.min(heightScale, widthScale);
211: return new Dimension((int) Math.round(scale
212: * inOrigImage.getWidth()), (int) Math.round(scale
213: * inOrigImage.getHeight()));
214: }
215:
216: public MimeTypeMap getMimeTypeMap() {
217: return fieldMimeTypeMap;
218: }
219:
220: public void setMimeTypeMap(MimeTypeMap inMimeTypeMap) {
221: fieldMimeTypeMap = inMimeTypeMap;
222: }
223: }
|