/**
*
*/
package org.inbio.m3s.util;
import java.util.StringTokenizer;
import org.apache.log4j.Logger;
/**
* @author jgutierrez
*
*/
public class ImageMagickAPI {
private static Logger logger = Logger.getLogger(ImageMagickAPI.class);
//FIXME: no deberia estar aca
public static final int THUMBNAIL_MAX_SIZE = 170;
//FIXME: no deberia estar aca
public static final int STANDARD_MAX_SIZE = 480;
/**
*
* @param originalFileName
* @param destinyFileName
*/
public static void createThumb(String originalFileName, String destinyFileName) throws Exception {
logger.debug("on createThumb[originalFileName]: "+ originalFileName);
int scaledWidth = 0;
int scaledHeight = 0;
int sourceWidth = getWidth(originalFileName);
logger.debug("width: " + sourceWidth);
int sourceHeight = getHeight(originalFileName);
logger.debug("height: " + sourceHeight);
// gets the adecuated sizes for the thumbnail keeping the ratio
if (sourceWidth > sourceHeight) {
scaledWidth = THUMBNAIL_MAX_SIZE;
scaledHeight = getOtherSideMaxValue(THUMBNAIL_MAX_SIZE,
sourceWidth, sourceHeight);
} else { // (originalImage.getWidth() >= originalImage.getHeight()){
scaledHeight = THUMBNAIL_MAX_SIZE;
scaledWidth = getOtherSideMaxValue(THUMBNAIL_MAX_SIZE,
sourceWidth, sourceHeight);
}
String[] cmd = { "convert", originalFileName, "-resize",
scaledWidth + "X" + scaledHeight, destinyFileName };
// String command = "convert " + originalFileName + " -resize "
// + scaledWidth + "X" + scaledHeight + " " + destinyFileName;
OSCommand.run(cmd);
}
/**
*
* @param originalFileName
* @param destinyFileName
*/
public static void writeStandardSize(String originalFileName,
String destinyFileName) {
int scaledWidth = 0;
int scaledHeight = 0;
int sourceWidth = getWidth(originalFileName);
int sourceHeight = getHeight(originalFileName);
// gets the adecuated sizes for the thumbnail keeping the ratio
if (sourceWidth > sourceHeight) {
scaledWidth = STANDARD_MAX_SIZE;
scaledHeight = getOtherSideMaxValue(STANDARD_MAX_SIZE,
sourceWidth, sourceHeight);
} else { // (originalImage.getWidth() >= originalImage.getHeight()){
scaledHeight = STANDARD_MAX_SIZE;
scaledWidth = getOtherSideMaxValue(STANDARD_MAX_SIZE,
sourceWidth, sourceHeight);
}
String[] cmd = { "convert", originalFileName, "-resize",
scaledWidth + "X" + scaledHeight, destinyFileName };
// String command = "convert " + originalFileName + " -resize "
// + scaledWidth + "X" + scaledHeight + " " + destinyFileName;
OSCommand.run(cmd);
}
/**
* Calculates the best size for a resize image based on the dimensions of
* the original image. In case the sourceWidth < sourceHeight, the
* maxSideValue is the height of the resize image and the return value is
* the width. If the sourceWidth > sourceHeight, the maxSideValue is the
* width of the resize image and the return value is the height.
*
* @param maxSideValue
* value of the wished maximum side for the generated image
* @param sourceWidth
* value of the source image width
* @param sourceHeight
* value of the source image height
* @return the maximun value for the other side of the image.
*
*/
private static int getOtherSideMaxValue(int maxSideValue, int sourceWidth,
int sourceHeight) {
logger.debug("actualWidth='" + sourceWidth + "' actualHeight='"
+ sourceHeight + "'");
double actualRatio = 0;
int otherSideMaxValue;
// Determina el lado mas grande para asignarle 480 pixels
if (sourceWidth < sourceHeight) {
actualRatio = (double) sourceWidth / (double) sourceHeight;
otherSideMaxValue = (int) (actualRatio * maxSideValue);
} else {
actualRatio = (double) sourceHeight / (double) sourceWidth;
otherSideMaxValue = (int) (actualRatio * maxSideValue);
}
logger.debug("maxSide='" + maxSideValue + "' maxOtherSide='"
+ otherSideMaxValue + "'");
return otherSideMaxValue;
}
/**
* Gets the width of an image. [Tested with: .TIF, .JPG]. The Tiff files
* sucks because could more than one image, so when you try to get the width
* returns more than one result, so to know the width of the high def image
* you have to check all the given returned size's and select the biggest
*
* @param imageAddress
* @return the high resolution image width
*/
public static int getWidth(String imageAddress) {
String[] cmd = { "identify", "-format", "%w;", imageAddress };
//String command = "identify -format %w; " + imageAddress;
String commandResult = OSCommand.run(cmd);
int width = 0;
int tempWidth;
// gets the width of the high def image
StringTokenizer st = new StringTokenizer(commandResult, ";");
while (st.hasMoreTokens()) {
try {
tempWidth = Integer.parseInt(st.nextToken());
if (tempWidth > width)
width = tempWidth;
} catch (NumberFormatException nfe) {
// ignore number format exception
logger.error("number format exception");
} catch (Exception e) {
// ignore any other exception exception
logger.error("exception");
}
}
return width;
}
/**
*
* Gets the height of an image. [Tested with: .TIF, .JPG]. The Tiff files
* sucks because could more than one image, so when you try to get the
* height returns more than one result, so to know the width of the high def
* image you have to check all the given returned size's and select the
* biggest
*
* @param imageAddress
* @return
*/
public static int getHeight(String imageAddress) {
//String command = "identify -format %h; " + imageAddress;
String[] cmd = { "identify", "-format", "%h;", imageAddress };
String commandResult = OSCommand.run(cmd);
int height = 0;
int tempHeight;
// gets the height of the high def image
StringTokenizer st = new StringTokenizer(commandResult, ";");
while (st.hasMoreTokens()) {
try {
tempHeight = Integer.parseInt(st.nextToken());
if (tempHeight > height)
height = tempHeight;
} catch (NumberFormatException nfe) {
// ignore number format exception
} catch (Exception e) {
// ignore any other exception exception
}
}
return height;
}
/**
* TODO: fix the final period(".") of some metadata
*
* @param hexadecimalValue
* @return
*
* Works nice on Fedora flavors
*/
public static String identifyEXIF(String hexadecimalValue,
String imageAddress) throws IllegalArgumentException {
String[] cmd = { "identify", "-format",
"%[EXIF:#" + hexadecimalValue + "]", imageAddress };
String commandResult = OSCommand.run(cmd);
logger.debug("after executing the command: '"+commandResult+"'");
// FIXME: check why some metadata finish with a period "."?
while (commandResult.charAt(commandResult.length() - 1) == '.') {
commandResult = commandResult.substring(0,
commandResult.length() - 1);
}
return commandResult;
}
/**
* This method was created to solved the bug of the identify command on some
* newer imagemagick versions (+6.3.7) that donde work properly.
*
* This method deprecated the identifyEXIF(String, String).
*
* It's wired to GNU/Linux
*
* @param exifAttribute
* @param imageAddress
* @return the EXIF value
*/
public static String identifyEXIFMetadata(String exifAttribute, String imageAddress) throws IllegalArgumentException {
String[] cmd = { "identify", "-verbose", imageAddress};
// String command = "identify -format %[EXIF:#" + hexadecimalValue + "]
// "
// + imageAddress;
String commandResult = OSCommand.run(cmd);
// FIXME: check why some metadata finish with a period "."?
while (commandResult.charAt(commandResult.length() - 1) == '.') {
commandResult = commandResult.substring(0,
commandResult.length() - 1);
}
return commandResult;
}
}