Tuesday, 26 April 2011

nip2 as a GUI for ImageMagick

update: see this more recent post. This is now a standard part of nip2, try Filter / Magick.

VIPS has an operation, im_system_image(), that lets you run a command-line program on an image. You can use it to run ImageMagick commands from nip2's menus.


im_system_image() writes the image to a temporary file, creates another filename for the output, uses popen() to run a command on it, loads the output file and returns that image. It arranges for the temporary files to be deleted when they are no longer needed.

You can call this function from nip2. Load a test image (perhaps A1) and click Toolkits / Widgets / Scale to make a slider (perhaps A2). Now at the bottom of the column, type:
"convert %s -swirl " ++ print A2.value ++ " %s"
This will make A3, the template for the command-line we want to run. The first %s will soon get substituted for the input filename and the second for the output filename. If you drag the slider, you'll see that your command-line updates.

(You may need to edit this a bit. For example, on Windows, you might need to give the full path to the convert program, and you'll need a .exe suffix as well. You might want to use GraphicsMagick instead, in which case you'll need "gm" at the front)

Now type this:
im_system_image A1.value "%s.tif" "%s.tif" A3
This will run im_system_image on the VIPS image underlying the nip2 object A1, with "%s.tif" as the template for the input and the output filename. The %s in the input and output filename templates will be substituted for something like /home/john/.nip2-7.24.1/tmp/348963498523-, depending on your platform. You can use the filename templates to set the file format that is used to pass your image to the program you are running.

If everything works, you'll get a two-element list back with the first element being the processed image and the second being all the output that the program sent to stdout while it ran. To view the processed image, you need to wrap it up in nip2's Image class. Just run the constructor on it:
Image A4?0
That is, pull element zero out of A4 (the result of im_system_image) and use it to build an instance of Image.

Now drag your slider, and the image should update! The scale widget defaults to the range 0 to 255, which is not really right for swirl. Doubleclick on the A2 button and set the range to -360 to +360. You could set the caption to something like "Swirl angle" too.


You can make a menu item that does all this with a click. Click Toolkits / Edit, select the Filter toolkit (this seems like a good place for it) and copypaste this code in:
Swirl x = class _result {
_vislevel = 3;
angle = Scale "Swirl angle" (-360) 360 0;
_result
= Image (im_system_image x.value fmt fmt cmd)?0
{
prg = "convert";
options = "-swirl " ++ print angle.value;
cmd = join_sep " " [prg, "%s", options, "%s"];
fmt = "%s.tif";
}
}
Select File / Process to get nip2 to update. Now you can select any image and click Toolkits / Filter / Swirl to swirl it. It would be pretty easy to make menu items for all the ImageMagick commands this way. You could even write a tiny bit of Python or Ruby to generate the code for you from the ImageMagick website.

Finally, that was the simplest, but not the best way to make a menu item. Here's a slightly fancier version:
Swirl = class
Menuaction "_Swirl" "swirl an image" {
action x = class
_result {
_vislevel = 3;
angle = Scale "Swirl angle" (-360) 360 0;
_result
= map_unary swirl x
{
prg = "convert";
options = "-swirl " ++ print angle.value;
cmd = join_sep " " [prg, "%s", options, "%s"];
fmt = "%s.tif";
swirl x = Image (im_system_image x.value fmt fmt cmd)?0;
}
}
}
This version will work correctly with Groups (so you can automatically loop over sets of images) and have a mnemonic and a tooltip.

5 comments:

  1. Interesting. John, you mean that I can use all of filters from the ImageMagick as well as nip2 filters?

    That would be great!

    ReplyDelete
  2. That's right, you can use any command-line program from nip2 that reads one image in and writes one image out.

    I'll add something to the next version to make the executable extension available, So you can add the .exe automatically, if necessary.

    Nip2 will be unresponsive while the command runs and there's no way to interrupt a running command. Perhaps this could be fixed too.

    ReplyDelete
  3. Nip2 will be unresponsive while the command runs and there's no way to interrupt a running command

    Hmmm... considering that many ImageMagick routines are quite slow, that would be a good feature to interrupt it.

    By the way, I've got an email recently asking for a book (!) about nip2. The person asked me whenever he can buy a book from me :-) I mean, there is actualy a demand for a book. I can participate to that book as well :-)

    ReplyDelete
  4. We have a talk based on this post proposed for LGM11:

    http://create.freedesktop.org/wiki/Instant_VIPSMagick#Slides_Link

    Draft slides here:

    http://www.vips.ecs.soton.ac.uk/development/vips-14apr11b.pdf

    Though they aren't much more than a set of screendumps.

    ReplyDelete
  5. The Libre Graphics Meeting 2011 presentation Instant VIPS Magick is at http://river-valley.tv/instant-vipsmagick/

    ReplyDelete