Sunday, May 14, 2006

ImageMagick in servlets

ImageMagick is probably one of the best tools to convert between image formats and in one of my applications I try to make preview thumbnails of almost any image format -- so that seems to be a logical choice. JMagick claims to be an "open source Java interface of ImageMagick" and it looks impressive. However you have to do some special stuff to accomodate JNI in servlets. Furthermore JMagick doesn't work with some out-of-the-box ImageMagick installation -- it seems you have to compile ImageMagick yourself.

Another approach to circumvent all this is to call the convert utility as an external command Essentially you are calling "convert - jpg:-" as an external command and feeding it the source image as standard input and reading the converted image (in this case jpeg) as standard output (Note: This doesn't work with Windows 98). All the other options like scale should work that way, too.

Unfortuantely the Runtime.exec has some pitfalls so we end up with this rather luxurious solution:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class play {

/**
* @param args
*/
public static void main(String[] args) throws Exception {
//set up the demo streams
FileInputStream in = new FileInputStream("/home/german/projects/anat/i1377439.MRDC.106");
FileOutputStream out = new FileOutputStream("/tmp/out.jpg");
convertToJPEG(in,out);

}

public static void convertToJPEG(InputStream is, OutputStream os) throws IOException, InterruptedException{
System.out.println("Start ImageMagick...");
Process p = Runtime.getRuntime().exec("convert - jpg:-");
//initialize Gobblers
StreamGobbler inGobbler = new StreamGobbler(p.getInputStream(), os);
StreamGobbler errGobbler = new StreamGobbler(p.getErrorStream(), System.err);
//start them
inGobbler.start();
errGobbler.start();
copy2(is, new BufferedOutputStream(p.getOutputStream()));
p.getOutputStream().close();
System.out.println("Image copied...");
//copy2(p.getErrorStream(), System.err);
if (p.waitFor()!=0) {
System.err.println("Error");
}
System.out.println("End Process...");
}

public static void copy2(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[512];
while (true) {
int bytesRead = is.read(buffer);
if ( bytesRead == -1 ) break;
os.write(buffer, 0, bytesRead);
}
os.flush();
}//method
}//class


class StreamGobbler extends Thread
{
InputStream is;
OutputStream os;


StreamGobbler(InputStream is, OutputStream redirect)
{
this.is = new BufferedInputStream(is);
this.os = redirect;
}

public void run()
{
try
{
play.copy2(is, os);
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}



1 Comments:

Anonymous Anonymous said...

Vielen Dank, das hat mir einige Stunden Arbeit erspart!!!

2:56 AM

 

Post a Comment

<< Home