package com.wilutions.itol;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class ThumbnailHelper {
private static Logger log = Logger.getLogger("ThumbnailHelper");
public final static double THUMBNAIL_WIDTH = 200;
public final static double THUMBNAIL_HEIGHT = 145;
public static File makeThumbnail(File file) {
if (log.isLoggable(Level.FINE)) log.fine("makeThumbnail(" + file);
File thumbnailFile = null;
String type = getImageFileType(file);
if (type.isEmpty()) return thumbnailFile;
try {
BufferedImage image = ImageIO.read(file);
BufferedImage thumbnailImage = makeThumbnailImage(image, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
if (image == thumbnailImage) {
thumbnailFile = file;
}
else {
thumbnailFile = makeThumbnailFileName(file);
ImageIO.write(thumbnailImage, "png", thumbnailFile);
}
} catch (IOException e) {
log.log(Level.WARNING, "Failed to create thumbnail of " + file, e);
thumbnailFile = null;
}
if (log.isLoggable(Level.FINE)) log.fine(")makeThumbnail=" + thumbnailFile);
return thumbnailFile;
}
public static BufferedImage makeThumbnailImage(java.awt.Image image) {
return makeThumbnailImage(image, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
}
public static BufferedImage makeThumbnailImage(java.awt.Image image, double maxWidth, double maxHeight) {
BufferedImage thumbnailImage = toBufferedImage(image);
double wd = image.getWidth(null);
double ht = image.getHeight(null);
if (log.isLoggable(Level.FINE)) log.fine("image width=" + wd + ", height=" + ht);
// Compute scale width and height
if (wd > maxWidth || ht > maxHeight) {
double ratioX = maxWidth/wd;
double ratioY = maxHeight/ht;
double ratio = ratioX;
if (ratioY < ratio) {
ratio = ratioY;
}
if (log.isLoggable(Level.FINE)) log.fine("scale image ratio=" + ratio);
thumbnailImage = scale((BufferedImage)image, ratio);
}
return thumbnailImage;
}
/**
* Make file name as imageFile-thumbnail.png
* @param imageFile
* @return
* @throws IOException
*/
private static File makeThumbnailFileName(File imageFile) throws IOException {
String fileName = imageFile.getName();
String ext = "";
int p = fileName.lastIndexOf('.');
if (p >= 0) {
ext = fileName.substring(p);
}
File thumbFile = File.createTempFile("thumbnail", ext, Globals.getTempDir());
return thumbFile;
}
/**
* Scale image by given ratio.
* Algorithm found at
* http://stackoverflow.com/questions/1069095/how-do-you-create-a-thumbnail-image-out-of-a-jpeg-in-java
* @param source
* @param ratio
* @return Scaled image
*/
private static BufferedImage scale(BufferedImage source, double ratio) {
int w = (int) (source.getWidth() * ratio);
int h = (int) (source.getHeight() * ratio);
BufferedImage bi = getCompatibleImage(w, h);
Graphics2D g2d = bi.createGraphics();
double xScale = (double) w / source.getWidth();
double yScale = (double) h / source.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale);
g2d.drawRenderedImage(source, at);
g2d.dispose();
return bi;
}
private static BufferedImage getCompatibleImage(int w, int h) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
return image;
}
/**
* Return image file type.
* @param file
* @return png, jpg or ""
*/
public static String getImageFileType(File file) {
String fname = file.getName();
String type = "";
int p = fname.lastIndexOf('.');
if (p >= 0) {
type = fname.substring(p+1).toLowerCase();
}
switch (type) {
case "png": case "jpg": case "gif": break;
default: type = "";
}
return type;
}
@SuppressWarnings("unused")
private static javafx.scene.image.Image awtImageToFX(java.awt.Image image) throws Exception {
if (!(image instanceof RenderedImage)) {
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null),
BufferedImage.TYPE_INT_ARGB);
Graphics g = bufferedImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
image = bufferedImage;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write((RenderedImage) image, "png", out);
out.flush();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
return new javafx.scene.image.Image(in);
}
public static BufferedImage toBufferedImage(java.awt.Image img)
{
if (img instanceof BufferedImage)
{
return (BufferedImage) img;
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
}