31 May 2011

Playing with the Gimp server: my notebook

In the following post, I'll show how the Gimp can be used as a server that will read and execute some statements in the scheme programming language. The scheme script will be used to downlad, resize and filter an image from the web.

Starting the Gimp Server

Go in menu FiltersScript-FuStart Server

The original image


(3156 x 2538)Barbara McClintock in the lab at Cold Spring Harbor in 1947

The script

Here is the scheme script:
;load an image of Baraba McClintock (1983 Nobel Laureate) who discovered the transposons
(define img (car (file-uri-load
RUN-NONINTERACTIVE
"BarbaraMcClintock"
"http://upload.wikimedia.org/wikipedia/commons/f/f6/Barbara_McClintock_at_C.S.H._1947.jpg"
) ))
;;get the layer for this image
(define layer (car (gimp-image-get-active-layer img ) ))
;;scale the image so its' width is 400px
(gimp-image-scale img 400 (* 400 (/ (car (gimp-image-height img)) (car (gimp-image-width img)) ) ) )
;;call the filter Oilify
(plug-in-oilify RUN-NONINTERACTIVE img layer 7 1)
;;save this image as /tmp/mcclintock.png
(file-png-save-defaults RUN-NONINTERACTIVE img layer "/tmp/mcclintock.png" "BarbaraMcClintock")
;;end
view raw script.scm hosted with ❤ by GitHub

The java client

The following java client will send the previous scheme script to the gimp server. The simple protocol used by GIMP is described on this page.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.Socket;
public class GimpClient
{
private String host="localhost";
private int port=10008;
private void run(Reader r) throws Exception
{
StringBuilder schemeScriptBuilder=new StringBuilder();
int c;
while((c=r.read())!=-1) schemeScriptBuilder.append((char)c);
String schemeScript=schemeScriptBuilder.toString();
if(schemeScript.length()>Short.MAX_VALUE) throw new IOException("Script is too large ("+schemeScript.length()+")");
byte input[]=schemeScript.getBytes();
OutputStream out=null;
InputStream in=null;
Socket socket=null;
try
{
socket= new Socket(this.host,this.port);
//socket.setSoTimeout(10*1000);
out=socket.getOutputStream();
in=socket.getInputStream();
out.write('G');
short queryLength=(short)input.length;
out.write(queryLength/256);
out.write(queryLength%256);
out.write(input);
out.flush();
int G=in.read();
if(G!='G') throw new IOException("Expected first byte as G");
int code=in.read();
if(code!=0) throw new IOException("Error code:"+code);
int contentLength= in.read()*255 + in.read();
byte array[]=new byte[contentLength];
int nRead=0;
int n=0;
while((n=in.read(array, nRead, array.length-nRead))>0)
{
nRead+=n;
}
if(nRead!=contentLength) throw new IOException("expected "+contentLength+" but got "+nRead+" bytes");
System.out.println(new String(array));
}
catch(Exception err)
{
throw new IOException(err);
}
finally
{
if(in!=null) in.close();
if(out!=null) out.close();
if(socket!=null) socket.close();
}
}
public static void main(String[] args)
{
try {
GimpClient app=new GimpClient();
String script=null;
int optind=0;
while(optind<args.length)
{
if(args[optind].equals("-h"))
{
System.out.println("Pierre Lindenbaum.");
System.out.println("Options:");
System.out.println(" -H <host> default:"+app.host);
System.out.println(" -P <port> default:"+app.port);
System.out.println(" -e 'script' (optional)");
System.out.println("<stdin|files>");
return;
}
else if(args[optind].equals("-H"))
{
app.host=args[++optind];
}
else if(args[optind].equals("-P"))
{
app.port=Integer.parseInt(args[++optind]);
}
else if(args[optind].equals("-e"))
{
script=args[++optind];
}
else if(args[optind].equals("--"))
{
optind++;
break;
}
else if(args[optind].startsWith("-"))
{
System.err.println("Unnown option: "+args[optind]);
return;
}
else
{
break;
}
++optind;
}
if(script!=null && optind!=args.length)
{
System.err.println("Illegal number of arguments");
return;
}
if(script!=null)
{
StringReader r=new StringReader(script);
app.run(r);
r.close();
}
else if(optind==args.length)
{
app.run(new InputStreamReader(System.in));
}
else
{
while(optind< args.length)
{
String inputName=args[optind++];
FileReader in=new FileReader(inputName);
app.run(in);
in.close();
}
}
}
catch (Exception err)
{
err.printStackTrace();
}
}
}
view raw GimpClient.java hosted with ❤ by GitHub

>javac GimpClient.java
>java GimpClient input.scm
Success

The result




That's it,


Pierre