/*
* Copyright 2013 James Moger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.moxie.ant;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.moxie.Build;
/**
* Generates thumbnails from all PNG images in the source folder and saves
* them to the destination folder.
*/
public class MxThumbs extends MxTask {
File sourceDirectory;
int maxDimension;
File destinationDirectory;
String input = "png";
String output = "png";
public MxThumbs() {
super();
setTaskName("mx:thumbnailer");
}
public void setMaximumDimension(int max) {
this.maxDimension = max;
}
public void setSourcedir(File dir) {
this.sourceDirectory = dir;
}
public void setDestdir(File dir) {
this.destinationDirectory = dir;
}
public void setTodir(File dir) {
this.destinationDirectory = dir;
}
public void setInput(String type) {
this.input = type;
}
public void setOutput(String type) {
this.output = type;
}
public void execute() {
Build build = getBuild();
if (destinationDirectory == null) {
getConsole().error("Please specify a destination directory!");
throw new RuntimeException();
}
if (maxDimension == 0) {
getConsole().error("Please specify a maximum dimension!");
throw new RuntimeException();
}
if (sourceDirectory == null) {
getConsole().error("Please specify an source directory!");
throw new RuntimeException();
}
destinationDirectory.mkdirs();
File[] sourceFiles = sourceDirectory.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith("." + input);
}
});
if (sourceFiles != null) {
build.getConsole().log("Generating {0} {1}", sourceFiles.length, sourceFiles.length == 1 ? "thumbnail" : "thumbnails");
for (File sourceFile : sourceFiles) {
String name = sourceFile.getName();
name = name.substring(0, name.lastIndexOf('.') + 1) + output;
File destinationFile = new File(destinationDirectory, name);
try {
Dimension sz = getImageDimensions(sourceFile);
int w = 0;
int h = 0;
if (sz.width > maxDimension) {
// Scale to Width
w = maxDimension;
float f = maxDimension;
// normalize height
h = (int) ((f / sz.width) * sz.height);
} else if (sz.height > maxDimension) {
// Scale to Height
h = maxDimension;
float f = maxDimension;
// normalize width
w = (int) ((f / sz.height) * sz.width);
}
build.getConsole().debug(1, "thumbnail for {0} as ({1,number,#}, {2,number,#})",
sourceFile.getName(), w, h);
BufferedImage image = ImageIO.read(sourceFile);
Image scaledImage = image.getScaledInstance(w, h, BufferedImage.SCALE_SMOOTH);
BufferedImage destImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
destImage.createGraphics().drawImage(scaledImage, 0, 0, null);
FileOutputStream fos = new FileOutputStream(destinationFile);
ImageIO.write(destImage, output, fos);
fos.flush();
fos.getFD().sync();
fos.close();
} catch (Throwable t) {
build.getConsole().error(t, "failed to generate thumbnail for {0}", sourceFile);
}
}
}
}
/**
* Return the dimensions of the specified image file.
*
* @param file
* @return dimensions of the image
* @throws IOException
*/
Dimension getImageDimensions(File file) throws IOException {
ImageInputStream in = ImageIO.createImageInputStream(file);
try {
final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
if (readers.hasNext()) {
ImageReader reader = readers.next();
try {
reader.setInput(in);
return new Dimension(reader.getWidth(0), reader.getHeight(0));
} finally {
reader.dispose();
}
}
} finally {
if (in != null) {
in.close();
}
}
return null;
}
}