/* ImageMagickUtil.java created by jrochkind on Thu 24-Apr-2003 */
import com.webobjects.foundation.*;
import com.webobjects.eocontrol.*;
import com.webobjects.eoaccess.*;
import com.webobjects.appserver.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
/* Utility methods that deal with images by calling the ImageMagick software
as an external process */
/* Dealing with Runtime.exec in a thread-safe way is tricky! Sorry for that.
I used the article at
http:as a guide for understanding how to do it right. */
public class ImageMagickUtil {
protected static final String imUtilLocationPath; static {
String locProp = System.getProperty("imUtilPath");
String osName = System.getProperty("os.name");
if ( locProp != null ) {
imUtilLocationPath = locProp;
}
else if ( osName.indexOf("Windows") != -1 ) {
imUtilLocationPath = "C:\\Program Files\\ImageMagick-5.5.6-Q8\\";
}
else {
imUtilLocationPath = "/export/home/webob/ImageMagick/bin/";
}
}
protected static final String imIdentifyCommand = "identify";
protected static final String imConvertCommand = "convert";
public static ImageProperties getImageSize(String filePath) throws IMException {
return getImageSize( new java.io.File(filePath) );
}
public static ImageProperties getImageSize(java.io.File imageFile) throws IMException {
String filePathToImage = imageFile.getPath();
String[] cmdArray = new String[] {
imUtilLocationPath + imIdentifyCommand,
"-format", "%w\n%h", filePathToImage
};
NSMutableArray stdOutContents = new NSMutableArray();
NSMutableArray stdErrContents = new NSMutableArray();
int resultCode = -1;
try {
resultCode = exec(cmdArray, stdOutContents, stdErrContents);
}
catch (IOException ioE ) {
throw new IMException("Could not exec imagemagick process: " + ioE.getMessage(), cmdArray, null);
}
catch ( InterruptedException intE ) {
throw new IMException("imagemagick process interrupted! " + intE.getMessage(), cmdArray, null);
}
if ( resultCode != 0 ) {
IMException e = new IMException("Identify failed! ", cmdArray, stdErrContents);
e.exitValue = resultCode;
throw e;
}
if ( stdOutContents.count() >= 2 ) {
String widthStr = (String) stdOutContents.objectAtIndex(0);
String heightStr = (String) stdOutContents.objectAtIndex(1);
Integer width = new Integer( widthStr );
Integer height = new Integer( heightStr );
ImageProperties p = new ImageProperties();
p.width = width;
p.height = height;
return p;
}
else {
throw new IMException("Unexpected output of imagemagick process", cmdArray, stdErrContents);
}
}
public static void resizeImage(String sourceFilePath, String outFilePath, int maxWidth, int maxHeight)
throws IMException {
if ( outFilePath == null ) {
outFilePath = sourceFilePath;
}
/*else if ( NSPathUtilities.pathExtension( outFilePath ) == null ) {
outFilePath = NSPathUtilities.stringByAppendingExtension( outFilePath,
NSPathUtilities.pathExtension(sourceFilePath));
}*/
StringBuffer dimensionBuffer = new StringBuffer();
if ( maxWidth != -1) {
dimensionBuffer.append(maxWidth);
}
dimensionBuffer.append( "x" );
if ( maxHeight != -1) {
dimensionBuffer.append( maxHeight );
}
String dimensionDirective = dimensionBuffer.toString();
String[] cmdArray = new String[] {
imUtilLocationPath + imConvertCommand,
"-size", dimensionDirective,
sourceFilePath,
"-resize", dimensionDirective,
"+profile", "*",
outFilePath
};
NSMutableArray stdErrContents = new NSMutableArray();
NSMutableArray stdOutContents = new NSMutableArray();
int resultCode;
try {
resultCode = exec( cmdArray, stdOutContents, stdErrContents );
}
catch (IOException ioE ) {
throw new IMException("Could not exec imagemagick process: " + ioE.getMessage(), cmdArray, null);
}
catch ( InterruptedException intE ) {
throw new IMException("imagemagick process interrupted! " + intE.getMessage(), cmdArray, null);
}
if ( resultCode != 0 ) {
IMException e = new IMException("Conversion failed! ", cmdArray, stdErrContents);
e.exitValue = resultCode;
throw e;
}
}
public static int exec(String[] cmdArray, NSMutableArray stdOut, NSMutableArray stdErr) throws IOException, InterruptedException {
Process process = Runtime.getRuntime().exec( cmdArray );
StreamGrabber errGrabber = new StreamGrabber( process.getErrorStream(), stdErr );
StreamGrabber outGrabber = new StreamGrabber( process.getInputStream(), stdOut );
errGrabber.start();
outGrabber.start();
return process.waitFor();
}
static class StreamGrabber extends Thread
{
InputStream inputStream;
NSMutableArray array;
boolean done = false;
Exception exceptionEncountered;
StreamGrabber(InputStream is, NSMutableArray a)
{
super("StreamGrabber");
this.inputStream = is;
this.array = a;
}
public void run()
{
try {
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
{
if ( array != null ) {
array.addObject(line);
}
}
}
catch ( java.io.IOException e) {
setExceptionEncountered( e );
}
setDone( true );
}
public synchronized void setDone(boolean v) {
done = v;
}
public synchronized boolean done() {
return done;
}
public synchronized Exception exceptionEncountered() {
return exceptionEncountered;
}
public synchronized void setExceptionEncountered(Exception e) {
exceptionEncountered = e;
}
public boolean didEncounterException() {
return exceptionEncountered() != null;
}
}
public static class IMException extends Exception {
protected int exitValue;
protected String processErrorMessage;
protected String invocationLine;
protected String message;
public IMException() {
super();
}
public IMException(String s) {
super();
message = s;
}
public IMException(String messagePrefix, String[] cmdArray, NSMutableArray stdErr) {
super();
if ( cmdArray != null ) {
invocationLine = new NSArray( cmdArray ).componentsJoinedByString(" ");
}
if ( stdErr != null ) {
processErrorMessage = stdErr.componentsJoinedByString("; ");
}
StringBuffer b = new StringBuffer();
b.append( messagePrefix );
b.append(". invocation line: ");
b.append( invocationLine );
b.append(". error output: " );
b.append( processErrorMessage );
message = b.toString();
}
public int exitValue() {
return exitValue;
}
public String processErrorMessage() {
return processErrorMessage;
}
public String invocationLine() {
return invocationLine;
}
public void setInvocationLine( String[] cmdArray ) {
invocationLine = new NSArray(cmdArray).componentsJoinedByString(" ");
}
public String getMessage() {
return message;
}
}
public static class ImageProperties extends Object {
protected Integer height;
protected Integer width;
public ImageProperties() {
super();
}
public Integer height() {
return height;
}
public Integer width() {
return width;
}
}
}