package net.trevize.galatee;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import javax.imageio.ImageIO;
import javax.media.jai.InterpolationNearest;
import javax.media.jai.JAI;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
//import net.sourceforge.jiu.codecs.CodecMode;
//import net.sourceforge.jiu.codecs.PNMCodec;
//import net.sourceforge.jiu.codecs.UnsupportedCodecModeException;
//import net.sourceforge.jiu.data.MemoryRGB24Image;
//import net.sourceforge.jiu.data.PixelImage;
//import net.sourceforge.jiu.ops.MissingParameterException;
//import net.sourceforge.jiu.ops.OperationFailedException;
/**
*
* @author Nicolas James <nicolas.james@gmail.com> [[http://njames.trevize.net]] ImageUtils.java -
* May 26, 2009
*/
public class ImageUtils {
public static final int RGB = 0x00FFFFFF;
public static final int R = 0x00FF0000;
public static final int G = 0x0000FF00;
public static final int B = 0x000000FF;
public static final int ALPHA = 0xFF000000;
public static int getR(Integer r) {
return (r & R) >> 16;
}
public static int setR(int pix, Integer r) {
return (pix & ~R) | (r << 16 & R);
}
public static int getG(Integer g) {
return (g & G) >> 8;
}
public static int setG(int pix, Integer g) {
return (pix & ~G) | (g << 8 & G);
}
public static int getB(Integer b) {
return (b & B);
}
public static int setB(int pix, Integer b) {
return (pix & ~B) | (b & B);
}
public static int getAlphaChannel(Integer a) {
return (a & ALPHA);
}
public static String rgb2String(Integer i) {
return "(" + getR(i) + "," + getG(i) + "," + getB(i) + ")";
}
public static int[][] toGreyLevel(BufferedImage bi) {
int[][] img = new int[bi.getWidth()][bi.getHeight()];
for (int i = 0; i < bi.getWidth(); ++i) {
for (int j = 0; j < bi.getHeight(); ++j) {
//using CIE recommendation 601.
img[i][j] = (int) (ImageUtils.getR(bi.getRGB(i, j)) * 0.299
+ ImageUtils.getG(bi.getRGB(i, j)) * 0.587 + ImageUtils
.getB(bi.getRGB(i, j)) * 0.114);
if (img[i][j] > 255) {
img[i][j] = 255;
} else if (img[i][j] < 0) {
img[i][j] = 0;
}
}
}
return img;
}
/**
* A static method for creating a BufferedImage object using the ImageIO.read(...) static method.
* If the ImageIO.read(...) method throws an exception, the image is rewrite using ImageMagick
* convert through a SystemCommandHandler2 object in the temporary directory of the Operating
* System, when the method try to reload the image.
*
* @param path to the image to load
* @return BufferedImage the created BufferedImage object
*/
public static BufferedImage loadImage(String path) {
BufferedImage bimg = null;
try {
bimg = ImageIO.read(new File(path));
} catch (Exception e) {
e.printStackTrace();
File tmp_image_file = null;
try {
tmp_image_file = File.createTempFile(""
+ Calendar.getInstance().getTimeInMillis(), ".tmp");
} catch (IOException e2) {
e2.printStackTrace();
}
SystemCommandHandler2 sch = new SystemCommandHandler2();
try {
String command = "convert "
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ path
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ " "
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ tmp_image_file.getCanonicalPath()
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER;
String[] commands = new String[1];
commands[0] = command;
sch.exec(commands);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
bimg = ImageIO.read(tmp_image_file);
} catch (IOException e1) {
e1.printStackTrace();
System.err.println("Unable to load the image " + path);
}
}
return bimg;
}
/**
* A static method for creating a BufferedImage object using the JAI library. static method. If
* the JAI.create(...) method throws an exception, the image is rewrite using ImageMagick convert
* through a SystemCommandHandler2 object in the temporary directory of the Operating System,
* when the method try to reload the image.
*
* @param path to the image to load
* @return BufferedImage the created BufferedImage object
*/
public static BufferedImage JAI_loadImage(String path) {
BufferedImage res = null;
try {
PlanarImage img = (PlanarImage) JAI.create("fileload", path);
res = img.getAsBufferedImage();
//free memory.
img.dispose();
} catch (Exception e) {
System.out.println("error when loading image " + path);
e.printStackTrace();
/*
* Maybe the exception is due to:
* Corrupt JPEG data: premature end of data segment
*
* So, a solution is to use a tmp file that is the rewritten
* image using the convert tool of ImageMagick.
*/
//create the temporary file.
File tmp_image_file = null;
try {
tmp_image_file = File.createTempFile(""
+ Calendar.getInstance().getTimeInMillis(), ".tmp");
} catch (IOException e1) {
e1.printStackTrace();
}
SystemCommandHandler2 sch = new SystemCommandHandler2();
try {
String command = "convert "
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ path
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ " "
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ tmp_image_file.getCanonicalPath()
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER;
String[] commands = new String[1];
commands[0] = command;
sch.exec(commands);
} catch (IOException e1) {
e1.printStackTrace();
}
//try again to load the image.
try {
PlanarImage img = (PlanarImage) JAI.create("fileload",
tmp_image_file.getPath());
res = img.getAsBufferedImage();
//free memory.
img.dispose();
} catch (Exception e1) {
System.out.println("Unable to load the image " + path);
e1.printStackTrace();
}
}
return res;
}
/**
* A static method to write a BufferedImage in a PNG file.
*
* @param img the BufferedImage object
* @param path the path of the file to create
*/
public static void writeBufferedImage(BufferedImage img, String path) {
File f = new File(path);
try {
ImageIO.write(img, "png", f);
} catch (IOException e) {
e.printStackTrace();
}
}
// public static BufferedImage loadPPM(String path) {
// // load the image in the PPM format using the JIU library
// PixelImage pi = null;
//
// try {
// PNMCodec codec = new PNMCodec();
// codec.setFile(path, CodecMode.LOAD);
// codec.process();
// codec.close();
// pi = codec.getImage();
// } catch (UnsupportedCodecModeException e) {
// e.printStackTrace();
// } catch (MissingParameterException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// } catch (OperationFailedException e) {
// e.printStackTrace();
// }
//
// MemoryRGB24Image mi = ((MemoryRGB24Image) pi);
//
// int width = mi.getWidth();
// int height = mi.getHeight();
//
// BufferedImage img = new BufferedImage(width, height,
// BufferedImage.TYPE_INT_ARGB);
//
// //copy the ppm image in a BufferedImage
// for (int i = 0; i < width; ++i) {
// for (int j = 0; j < height; ++j) {
//
// //retrieve the rgb value in the ppm
// int r = mi.getSample(0, i, j);
// r <<= 16;
// int g = mi.getSample(1, i, j);
// g <<= 8;
// int b = mi.getSample(2, i, j);
// int rgb = ImageUtils.ALPHA | r | g | b;
//
// //update the BufferedImage pixel value
// img.setRGB(i, j, rgb);
// }
// }
//
// return img;
// }
public static Dimension getImageSize(String path) {
BufferedImage bi = JAI_loadImage(path);
/*
* if there is a problem while loading the image we return null.
*/
if (bi == null) {
return null;
}
Dimension res = new Dimension(bi.getWidth(), bi.getHeight());
bi = null;
return res;
}
/**
* get the size of a scaled image in keeping the with/height ratio and considering a maximum with
* and a maximum height.
*
* @param width
* @param height
* @param maxWidth
* @param maxHeight
* @return
*/
public static Dimension getScaledSize(int width, int height, int maxWidth,
int maxHeight) {
Dimension imageDim = new Dimension();
if (width <= maxWidth && height <= maxHeight) {
imageDim.width = width;
imageDim.height = height;
} else {
float scale_x = (float) maxWidth / (float) width;
float scale_y = (float) maxHeight / (float) height;
if (scale_x < scale_y) {
imageDim.width = (int) (width * maxWidth / width);
imageDim.height = (int) (height * maxWidth / width);
} else {
imageDim.width = (int) (width * maxHeight / height);
imageDim.height = (int) (height * maxHeight / height);
}
}
return imageDim;
}
public static BufferedImage resizeImage(int maxWidth, int maxHeight,
BufferedImage bi, boolean keepRatio) {
int width = bi.getWidth();
int height = bi.getHeight();
Dimension imageDim;
if (keepRatio) {
imageDim = getScaledSize(width, height, maxWidth, maxHeight);
} else { //don't keep ratio.
imageDim = new Dimension(maxWidth, maxHeight);
}
BufferedImage res = new BufferedImage(imageDim.width, imageDim.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = res.createGraphics();
g.drawImage(bi.getScaledInstance(imageDim.width, imageDim.height,
Image.SCALE_SMOOTH), 0, 0, null);
g.dispose();
return res;
}
public static BufferedImage JAI_loadAndResizeImage(int maxWidth,
int maxHeight, String path, boolean keepRatio) {
PlanarImage img = (PlanarImage) JAI.create("fileload", path);
ParameterBlockJAI pb = new ParameterBlockJAI("scale");
pb.addSource(img);
Dimension scaled_size = null;
try {
scaled_size = getScaledSize(img.getWidth(), img.getHeight(),
maxWidth, maxHeight);
} catch (Exception e) {
System.out.println("Unable to load image: " + path);
System.out.println(e.getMessage());
e.printStackTrace();
return null;
}
pb.setParameter("xScale", (float) scaled_size.width
/ (float) img.getWidth()); //x Scale Factor
pb.setParameter("yScale", (float) scaled_size.height
/ (float) img.getHeight()); //y Scale Factor
pb.setParameter("xTrans", 0.0F); //x Translate amount
pb.setParameter("yTrans", 0.0F); //y Translate amount
pb.setParameter("interpolation", new InterpolationNearest());
PlanarImage resized_img = JAI.create("scale", pb, null);
BufferedImage res = null;
try {
res = resized_img.getAsBufferedImage();
} catch (Exception e) {
System.out.println("JAI: Could not find mediaLib accelerator, continuing in pure Java mode.");
}
//free memory.
img.dispose();
resized_img.dispose();
return res;
}
public static BufferedImage JAI_loadAndResizeImage(int maxWidth,
int maxHeight, InputStream is, boolean keepRatio) {
PlanarImage img = (PlanarImage) JAI.create("stream", is);
ParameterBlockJAI pb = new ParameterBlockJAI("scale");
pb.addSource(img);
Dimension scaled_size = null;
try {
scaled_size = getScaledSize(img.getWidth(), img.getHeight(),
maxWidth, maxHeight);
} catch (Exception e) {
System.out.println("Unable to load image from input stream");
System.out.println(e.getMessage());
e.printStackTrace();
return null;
}
pb.setParameter("xScale", (float) scaled_size.width / (float) img.getWidth()); //x Scale Factor
pb.setParameter("yScale", (float) scaled_size.height / (float) img.getHeight()); //y Scale Factor
pb.setParameter("xTrans", 0.0F); //x Translate amount
pb.setParameter("yTrans", 0.0F); //y Translate amount
pb.setParameter("interpolation", new InterpolationNearest());
PlanarImage resized_img = JAI.create("scale", pb, null);
BufferedImage res = resized_img.getAsBufferedImage();
//free memory.
img.dispose();
resized_img.dispose();
return res;
}
public static void ImageMagick_resizeImage(String source,
String destination, int new_width, int new_height) {
SystemCommandHandler2 sch = new SystemCommandHandler2();
StringBuffer command = new StringBuffer();
command.append("convert ");
command.append("-resize " + new_width + "x" + new_height + " ");
command
.append(SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ source
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER);
command.append(" ");
command.append(SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ destination
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER);
String[] commands = new String[1];
commands[0] = command.toString();
sch.exec(commands);
}
public static void ImageMagick_convertImage(String source,
String destination) {
SystemCommandHandler2 sch = new SystemCommandHandler2();
StringBuffer command = new StringBuffer();
command.append("convert ");
command
.append(SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ source
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER);
command.append(" ");
command.append(SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ destination
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER);
String[] commands = new String[1];
commands[0] = command.toString();
sch.exec(commands);
}
public static void ImageMagick_convertImage(String source,
String destination, String color_space) {
SystemCommandHandler2 sch = new SystemCommandHandler2();
StringBuffer command = new StringBuffer();
command.append("convert ");
command.append("-colorspace " + color_space + " ");
command
.append(SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ source
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER);
command.append(" ");
command.append(SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER
+ destination
+ SystemCommandHandler2.ESCAPED_DOUBLE_QUOTE_CHARACTER);
String[] commands = new String[1];
commands[0] = command.toString();
sch.exec(commands);
}
}