home |  avr microcontroller & DIY electronics |  toolbox |  science club  |  tuxtalk |  photos |  e-cards |  Online-Shop


no preservatives added blog | computer and graphics corner | herbal treasure chest | splash into math | stardust | periodic table

Do magic with images on the shell

This article was written when ImageMagick hadn't split yet. It will work for ImageMagick and Graphics Magick.
In this article we look at some spells the wizard of ImageMagick can do using a collection of graphic tools as his raw ingredients and the shell as his magic wand.

[Illustration]

Doing magic

In the olden times wizards took their raw ingredients, mixed them together in a big pot, swang their magic wand, murmured their spells... and suddenly someone was turned into a frog. In our modern times wizards are like everyone else in society highly specialised and their spell books only contain a few useful spells for very specific tasks. So ImageMagick is no spell book for general use. In many aspects it can't compete with The Gimp or many other graphic programs but it has some specialised features that are very useful.
Its real strength lies in the possibility to automate a lot of its processes when working with it on the shell.

But before we are going to divulge some spells to you let's have a quick look at the raw ingredients first:

The raw ingredients

or What is ImageMagick?

ImageMagick is a collection of graphic tools to work with images. The tools are display, import, animate, montage, convert, mogrify, identify and combine.
Display: If you type "display &" a display window appears and you can work directly on the image. Via the menu you can open a file, save or delete it, flip or rotate, make changes to the colour or apply certain effects, e.g. implode, emboss the picture, put a frame around it and more.
With Import you can make screen shots of the entire screen or of certain images or windows.
Animate is a tool for animation. You can select a series of images to be displayed one after the other or you can view an animated gif image with it.
With Montage you can e.g. create a tiled image or get an image where you can see all single images that an animated gif consists of.
Convert is a very powerful tool. You can convert an image into another format e.g. a gif image into a jpg image or the other way round, you can change the size of an image and also apply a lot of other effects, e.g.to characoal, on the images.
Mogrify is very similar to convert with the big difference that with mogrify you overwrite the current image while with convert and the other tools you have to specify a file where the changed image is saved in. Therefore I almost never use it.
Identify gives you information about the image like its geometry, size, name, format etc.
Combine combines two or more images to another image. You can for example put a logo on every image.

To use the tools you type in the name of the tool, followed by the option you want to use, the image that is to be manipulated and the filename where you want to save the changed image in.
E.g. if you want to characoal tux1.gif with a factor of 3 and save it into tux1characoal.gif you will write:
convert -characoal 3 tux1.gif tux1characoal.gif

After this look at the raw ingredients let's now try some spells:

Some Spells

Changing the height and width of your images

Imagine you have a pile of images with the latest victims that you turned into a frog and want to put them on your webpage. In order to reduce loading time you want to make your images smaller.
With the convert tool you can make your images bigger or smaller or you can generate thumbnails.
The command
convert -geometry 60x80 image.gif out.gif
scales the image image.gif to a width of 60 and a height of 80 and writes the resulting image to out.gif.

To give all our images e.g. a height and width of 80 in one go you can write:
#!/bin/sh
for f in $* ;do
 convert -geometry 80x80 $f t_$f
 echo "<a href=\"$f\"><img src=\"t_$f\" width=\"80\" height=\"80\"></a>"
done
# end of script
(Type this lines into any text editor of your choice (vi, emacs, nedit, kedit...) and save it under mksmallimage in your home directory. Then go to the bash shell and type
chmod 755 /home/katja/mksmallimage
(use the name of your home directory instead of katja) Then you can use the script by typing /home/katja/mksmallimage xxx.jpg *.gif It converts all gif files plus the xxx.jpg file.)

So if I have a bunch of jpg images that need to get smaller I type:
  /home/katja/mksmallimage *jpg

and I have the smaller images that start with t_ and the original ones.
If I don't want to keep the original I can delete them. For this I first create a new directory and name it "keep" or whatever you want to name it.
 mkdir keep

Then you move the images that you want to keep that all start with t_ into this directory:
 mv t_* keep/

I type ls to see if now only the images I want to delete are left. If yes, I can continue and delete them:
 rm *

Now only my directory keep is left. I move the files from keep into the directory:
 mv keep/* .

and delete keep:
 rmdir keep/ 


Now I prefer to have them end with "small" and not have "t_" at the beginning.
So I tell the computer that I want to rename the images and substitute the ".jpg" ending with "small.jpg" and that I want to substitute (that's the s in the command line) "t_" with nothing:
 rename.pl 's/.jpg/small.jpg/' t_*
rename.pl 's/t_//' t_*


Creating overview pictures

You have a CD with a collection of all the people you turned into frogs in the last couple of years. Now your rivaling wizard who is very jealous of you wants the proof that you even turned his dog into a frog ones. And now you spend the whole day looking for that photo. This could have been avoided if you had had an overview picture with all the pictures on your CD. With ImageMagick it's very easy to create one:
display "vid:*.jpg" 
This will generate a visual image directory of all your jpg images in the current directory. Or:
display "vid:frog/*" 
will generate a visual image directory of all your images in your frog-directory.
With a right mouse click on any of the images you get a menu where you can select "Load" to see the image in its full size.

[visual image directory]


This is a very easy way to create an overview picture but depending on your computer it takes time for the visual image directory to be generated and it consumes a lot of memory if you have a large number of images. Therefore we will write a little htmlthumbnails script now which is a little bit less demanding in that respect and then build a webpage where you can click on any of the thumbnails and get the original image.

The html code for this would look as follows:
<a href="file.gif"><img src="t_file.gif" width="60" height="80"></a>
The original file here is file.gif and the thumbnail is t_file.gif.
Now we write a script that will generate the thumbnails and write the html code for us.
for f in $* ;do
 convert -geometry 80x80 $f t_$f
 echo "<a href=\"$f\"><img src=\"t_$f\" width=\"80\" height=\"80\">"
done
The above script will loop over all images as specified on the command line, generate the thumbnails and write the html code to the screen. We can then copy and paste the html code into our webpage.
For a complete shell script we add some help text and error checking. Here is our final shell script, called htmlthumbnails :
htmlthumbnails (html for viewing), htmlthumbnails (text for download)

Changing the image format

Convert can not only change the size of an image but the format as well. E.g. you can change a gif image to jpg or the other way round. The command to do this is simply:
convert image.gif image.jpg
Convert knows from the extension of the file name which format it has to use.
To change the image format from jpg to gif for a lot of images use:
for f in $* ;do
 if echo "$f" | grep -i "jpg$" > /dev/null ; then
   gif=`echo "$f" | sed 's/jpg$/gif/i'`
   echo "converting  $f to $gif ..."
   convert 80x80 $f $gif
 else
   echo echo "$f is not a jpg file, ignored"
 fi
done
There is also quite a large number of other formats that Image Magick knows as well.

Putting a logo into all your pictures

We would like to add a litte logo like the one you can see on the right to a number of images. [linuxfocus stamp]

This logo should be a small transparent gif image. Our logo should be placed like a little signature in the lower right corner in the final image as you can see in the following Tux image:

[tux with logo]

What is the command to do this?
The combine tool can be used to combine 2 images into a new one. Several options tell the program how to do it:
combine -gravity SouthEast -compose Over img.jpg logo.gif stamp_img.jpg
The option "gravity SouthEast" puts the logo.gif in the lower right corner. "compose Over" says that we will replace the image by the logo in the places where they overlap.

To get a fully functional shell script we put the command into a for-loop and again add some help text and error checking. Here is our final shell script, called stampimages :
stampimages (html for viewing), stampimages (text for download)

Getting information of picture properties

Identify displays details about the type of your images, their size and geometry. This looks e.g as follows:
identify  image.jpg
results in
image.jpg 340x254 DirectClass 13939b JPEG 0.1u 0:01
What can our wizard do with it? Well, to design good webpages that will display images while the page is still loading you should specify the exact geometry for all images. The html code would e.g look like this:
<img src="image.jpg" width="340" height="254" alt="[sample picture]">
When our images have different sizes and we don't know the exact height and width of each of them we can use identify to help us. We write a shell script that will read the output of "identify" and then print this line. The geometry of the image is the second parameter in the output string of the identify program. To get this parameter we use the command awk:
identify  image.jpg | awk '{print $2}'
results in
340x254
Now we have to split the geometry in width and height. This can be done with:
echo 340x254 | sed 's/[^0-9]/ /g' | awk '{print $1}'
which would give the width. The height can be obtained with:
echo 340x254 | sed 's/[^0-9]/ /g' | awk '{print $2}'
Don't focus too much on the exact shell commands. If you don't understand them completely yet then just accept them as given. There will be an article about shell programming in the next issue of LinuxFocus where we will explain all of its magic. The final shell script looks as follows:
file=$1
geometry=`identify $file | awk '{print $2}'`
# geometry can be 563x144+0+0 or 75x98
# we need to get rid of the plus (+) and the x characters:
width=`echo $geometry | sed 's/[^0-9]/ /g' | awk '{print $1}'`
height=`echo $geometry | sed 's/[^0-9]/ /g' | awk '{print $2}'`
echo "<img src=\"$file\" width=\"$width\" height=\"$height\">"
To get the complete shell script we again add a help text and some error checking. Here is our final shell script, called imgsrcline :
imgsrcline (html for viewing), imgsrcline (text for download)


While playing with ImageMagick I found that there is sometimes a discrepancy between the documentation and the actual functionality. Some features are also not very stable. However if you stick to the things that were demonstrated above then you will see that it is useful. The functions listed above do work. I used ImageMagick-4.2.9 , ImageMagick-5.2.9 and ImageMagick-5.3.0 and the things you learned here do work across all these versions.

I hope you got an idea now what you can do with ImageMagick and will use the scripts or even start creating your own spells.
Have fun!

References





Copyright © 2004-2024 Katja Socher, tuxgraphics.org