ImageMagick v6 Examples --
Basic Usage

Index
ImageMagick Examples Preface and Index
ImageMagick Command Line Processing
ImageMagick Commands
Image Sequences
Image Attributes and Settings
ImageMagick Operational Controls

Here we explain in detail the command line processing that IM follows, some of the new image processing abilities, the ideas, philosophy, and methodology, and what is actually going on, internally.

With this background knowledge the rest of the examples provided pages becomes much clearer. Even if you only use the Application Program Interface (API), this section is well worth knowing and understanding.


ImageMagick Command Line Processing

Why did the command line style change!  or...
The problem with previous versions of IM

In previous major version of ImageMagick (version 5.5.7 and earlier) the command line interface into the IM library has been prone to problems involving the order in which operations were performed. It was very haphazard, and confusing to anyone trying to make sense of what was actually going on. Also, what worked one time may not work in the same order another time, as the author of IM, constantly battled with the interface to get it to work as people expected.

The cause of the problem was that ImageMagick followed a fairly standard UNIX command line style...

command  [options]  input_image   output_image

As time went on this started to produce problems, as images are complex objects with an enormous number of operations that can be performed on them often involving other images.

As a consequence of this the above slowly expanded to become..

command  [options] image1 [options] image2 [options]  output_image

This worked, and is the basic style that was used in version 5.5.7.

The various image operations such as "-negate", "-resize", and "-crop", etc, could appear either before or after the image it was meant to apply to.

For example under version 5.5.7 the following two commands were equally valid and did the same thing.

  convert  -negate  image.gif   output.gif

  convert   image.gif  -negate  output.gif

The problem was what if you were dealing with two images! For example...

  convert -size 40x20 xc:red  xc:blue \
          -append   -rotate 90    append_rotate.gif
[IM Output]

The result (in IM v5.5.7) was that the two input images were rotated first, then appended together, producing a image like...

That is the "-rotate" operator would be applied BEFORE the "-append" which is probably not what the user intended.


[IM Output] With ImageMagick version 6 however, the operators will always be applied in the command line order as given by the user. That is, the two images will be appended together first, then the result of the append will be rotated, producing this...

If the user actually intended to do the rotations before the append, he can explicitly ask IM v6 to do it in that order.

  convert -size 40x20 xc:red  xc:blue \
          -rotate 90  -append    append_rotate_bad.gif

This sort of fine control was just beyond previous versions of IM, and would probably have required a pipeline, or intermediate save images to achieve it.

The solution to the problem, unfortunately required a drastic measure and some incompatibility. On the other hand just about every 'simple' command that worked in IM version 5 will works as you would expect IM version 6.

In essence command line usage in versions before version 6 was ill-defined and in my thinking broken, producing numerous odd and unexpected results.

Types of Options - Operators and Settings...

A summary of the following is now also available from the ImageMagick Website on The Anatomy of the Command Line.

All command line options will now fall into two basic groups: 'settings' and 'image operators'. Settings set values, Operators actually preform some action.

Setting Options
are command line options that only save information, that will be used later by other 'image operators'. That is they do not do anything, except set some value, to be used later. Many of the options have both a '-' and a '+' style. The latter is generally used to turn off the setting, or reset it to its normal default state. This allow you remove the effect of a setting quickly and simply.

For example "+gravity" will return the gravity setting to the initial 'gravity none' state. Settings can be further divided into a number of sub-categories...

Operation Settings which control how later operators function. They set the colors, and fonts that may be used by an operator, control placement of images and text, the lookup of color from source images, control the method of processing by some of the more complex operators, etc., etc., etc..
-dither  -gravity  -fill  -background  -bordercolor  -stroke  -font  -pointsize  -strokewidth  -box  -affine  -virtual-pixel  -interpolate

Most setting options belong to this category.

Input Settings are specifically restricted to controlling the creation of images that are created or read in. Typically they are used to assign or override specific meta-data that is to be associated with the image(s) created after that setting was defined.

they are created or read in from an external file.

-label  -delay  -dispose  -page  -comment  -size

Remember, they are ONLY applied when an image is created or read in and are otherwise completely ignored.

Many settings define a string to be assigned which could include special escape characters, such as '%w' which will be replaced by the images width. These escapes are only filled in after the image has been read into memory, when the setting is actually assigned to the specific images meta-data.

A special operator, "+set" has been provided to change the meta-data assigned after an image has been read into memory or processed.

Output Settings which are only used during the writing or saving of images back to disk.

While they can be given anywhere on the command line, they are only applied when the image is written, either as the default last image filename argument operation, or via a "-write", or "-identify" operation.
-quality  -loop  -compression  -format  -path  -transparent-color

If not set, or turned off (using their plus '+' form), an appropriate default will be used. Generally this default is a saved value from the last image read in.

A few 'operation settings' such as the current "-background" color, is also assigned to the image, if the file format requires.

Control & Debugging Settings which control how IM, in general, performs its tasks. These includes...
-verbose  -debug  -warnings  -quiet  -monitor  -regard-warnings

See IM Operation Controls below, for more information on these special settings.

 
Image Operators
Are command line arguments that will modify the image(s) in some way. They are performed immediately when seen, and may use other 'setting options' that have been given previously on the command line.

These operators can be grouped into a few sub-categories...

Image Creation Operators which will read images from a file or pipeline, or generate new images. These include...
image.png  miff:-  xc:color  logo:  rose:  plasma:  gradient:  tile:

As 'operators' they are also performed immediately when seen on the command line. They only add new images to those already in memory, but do not touch those previously read.

Of course being operators, any previously defined 'settings' may effect them, especially the "-size" setting, which defines, or hints at the size of the image you want to create or read in, and other 'input settings', that may also have been defined, such as "-delay", and "-page"

Image Modification Operators will modify all images that have already been read into memory. Each image however is modified separately to every other image. They include operations such as...
-negate  -rotate  -crop  -flip  -flop  -wave  -resize  -repage  -set  -shadow  -scale  -sample  -swirl  -draw  +matte
And lots lots more...

Because all image operators are performed immediately when seen on the command line, they must be given after the images for which they are to operate have been read into memory.

If more than one image is present, all images are operated on, one at a time. As such you will have to be careful about what image(s) you have in the current image sequence.

Multi-Image Layer Operators are special in that they modify the whole current list of images as a single entity. They could replace the whole list with a single combined image, or modify each image depending on the other images either before or after it. They are used for alpha composition, animation handling, color channel handling, etc...
+append  -mosaic  -flatten  -fx  -composite  -combine  -separate  -coalesce  -deconstruct  -layers  -clut

Remember the whole list is treated as a single entity, and images may be added, removed, or replaced. Most of the above operators usually merges multiple images into a single image.

The "-layers" operator method 'composite' is currently the only operator that may spilt the current image sequence into two separate sequences for merger, based on a special 'null:' image marker.

Image List or Sequence Operators effect the ordering of images currently in memory.
(  )  -swap  -delete  -clone  -insert  -reverse

The images themselves are not modified, only re-ordered, duplicated, or deleted. See Image Sequences below for more details.

Note that parenthesis '(' and ')' may require backslashing or quoting, to prevent any special meaning given to it by the Command Line shell Interface (CLI).

Special Operators are operators that do things in unusual and non-standard ways (compared to the above).
-geometry  -version  -list

The "-geometry" operator is special as it is the only operator that only effects one image (the last) in the image sequence, rather than effecting all of the images in some way. It is only provided for backward compatibility and special alpha composition requirements. See Geometry, resize just the last image for more details.

The other two "-version" and "-list" are information generating operators, and causes IM to explicitly quit, after returning the requested information. See IM Operational Controls below, for more information on these options.

I hope the separation of options into settings and operators is clear as it is vital to the way IM now works.

Remember under version 6 of ImageMagick...

Settings are saved for later use,
while Operators are applied immediately.

This is what makes version 6 different from every previous version of IM. All options are defined to be a 'setting' or an 'operator' and the order will determine exactly when, and to what images, the option will be applied to.

The IM Examples Options Reference can be used to identify what is an 'setting' and what is an 'operator'.

Working Example of an IM Command

Let's take a look at an example, and how it will be processed by IM version 6.

  convert  eye.gif news.gif -append    storm.gif tree.gif \
           -background skyblue +append    output.gif
[IM Output]

Let's break this down and look at what IM v6 does...
Argument     Action Performed     Images in Seq

convert Initialize and Create an empty 'image sequence' empty seq
eye.gif Read in image and add to end of current sequence 1 image
news.gif Add a second image into sequence (now with two images) 2 images
-append Take all images in current sequence, and append vertically.
All images are replaced by a single image.
1 (merged)
storm.gif Add another image to the image sequence 2
tree.gif And another 3
-background skyblue Set a 'background color' to be used later.
No changes are made to any images.
3
+append Join all 3 images in sequence horizontally
Current background color is used to fill the empty space
1 (merged)
output.gif As this is last argument, and as such is an explict -write operation. The single image in the current image sequence is written using the given filename. written

As you can see the processing of the command line in IM v6 is very straight forward, and logical, making the result predictable. And that is the point...

In previous versions, IM results were often not predictable and undefined when multiple operations were performed. You would have basically needed to try it to see what the result would be. Each previous release of IM would also probably have produced a different result as well!

Version 6 should see the end of that mess and everyone is urged to convert to it and re-program your image processing scripts to use it. As things are settled into this style of command line handling, you should see no further changes in your results except for bug fixes and operation improvements, as IM is expanded.

Legacy Command Line Style

Due to the fact that a lot of IM scripts out there use a command with a single image operator of the form...


command  -operator  input_image   output_image

That is you specified an image operator before you actually read the image to which the operator will be applied.

To handle this legacy situation, IM will save up all the image operators it sees, and apply them to the first image when it is finally seen on the command line. That is the above will work as if you wrote the wrote...


command  input_image   -operator  output_image

For example, this legacy command....

  convert  -flip  storm.gif   cmd_flip_legacy.gif
[IM Output]

Will produce the same result as this IM version 6 command...

  convert  storm.gif -flip  cmd_flip_postfix.gif
[IM Output]

The legacy command line style works, but has the same problems as IM version 5. All settings are applied before the first read, and all the operators are just saved away to be executed when the first image is read (and only on the first image). There is also no guarantee of the order of multiple operators will be the same as the order you give.

Also as operators are being save up until the first image is actually read, you may find repeating a command multiple times before reading the image may result in some of the earlier commands 'disappearing'. This is not a bug, but a miss-use of the legacy abilities of IM.

This style of command line is for legacy support only, and as such is depreciated, so should be avoided if at all possible. Any scripts containing this old style, should also be updated to do image reads before the operators you want to apply to them.

Command Line vs API

There is a couple of major differences between a command line IM, and using the Magick API's, such as PerlMagic, and MagickWand.

Only one Image List or Sequence
The command line only ever has one Image List or Sequence which can be worked on at any one moment. You can 'push' or save an image sequence, temporarily, and even 'clone' images from that 'backup', but you can't really work on two such sequences at the same time.

Other language API's on the other hand allow you to have as many separate image lists or 'wands' as you like, and you can work on any of them at any time, or transfer images between the various lists.

That means you can not easily do things such as merge or combine two separate image lists from the command line, though some methods have been worked out for special operations such as Multi-Layer Alpha Composition of Image Lists.

Direct Access to Pixel Data
Again you can so some math processing and merging of pixel data from the command line, but you can't easily look up attributes, or read and modify a specific pixel or area using the command line interface.

You can however merge and mathematically modify pixel data of images using the special FX Image Operator, but it is limited to transforming whole images, is interpreted, and very very slow.

API's can do this in a much more direct manner. Though some still feel the provided functions are limiting, however this API allows IM to use threaded programming, and to allow cloned images to share the same (unmodified) pixel data store.

Conditional Processing
While the IM command line interface can not modify images based on some image derived attribute. For example you can not process images differently depending on if the image uses a light background, or a dark background.

Yes you can do some limited and specific conditional actions using the FX Image Operator, or ask IM to adjust (rotate) an image's Orientation based on certain conditions, or only shrink and never enlarge when Resizing Images. But these are only handling special well known and common processing conditions.

The only truly practical way do conditional processing is to use separate commands and temporary files. For an example see the well commented Jigsaw Script.

API's on the other hand can do this type of conditional processing all in memory, as and when you need it.

Looped Processing
You also can not loop over each image, and do something different to each image based on the image 'scene' number. For example draw text at different sizes, or gradually blur an image. For any number of images.

Yes you can modify specific images in a image list. For example see Frame by Frame Modification of an Animation. But you must know how many images are in the image list, and 'un-roll' the loop to process each image in the list separately.

The only truly practical way to loop over images from the command line is to write out the individual images as separate image files (see Writing a Multi-Image Sequence and process them one at a time in an external scripted loop, for example see Appending Animations. Alternatively, generate the command with the un-rolled loop using a shell script, for example see shell script Programmed Positioning of Layered Images, or the various Distortion Animation shell script generators.

API's however have no problem with looping over multiple images, either in a single image sequence, or even multiple separate image sequences, or even with a whole array or data structure of image sequences.

If your application needs to be able to do any of these things (though few common applications need to do so) then an API may be better, than the command line.

The "conjure" program (see below) was originally designed to allow better scripted use of ImageMagick, allowing the use of multiple image lists. The improvements made to IM v6 "convert" has seen this experimental API fall into disuse.


ImageMagick Commands

While the bulk of these ImageMagick example pages use the "convert" command to process images, their are a number of other ImageMagick commands, which I'll briefly introduce here.

Some of these commands however can not be demonstrated properly on a web page. However I will try to give you hints and tips involving those command here, even if I can't actually show their output directly, here.

Convert -- Convert between Image formats
But also process and transform the images!

The "convert" command is the main workhorse of ImageMagick, and as such just about every set of examples in these pages uses this command. As such I will not cover the use of this command much here, but lets look at a little history instead.

The command original commands purpose when IM was first created was for the conversion of images in one image format into another. In fact it is still used for this purpose.

Because of this the command may not even read an image into memory, but may use secondary Delegate programs outside IM proper to do the conversion directly. This completely external aspect however has fallen into disuse over time, and lack of need, except as a means of reading in and writing out complex images file formats.

Over a long period of time some extra image processing features was added to make minor changes to images as they were transferred between formats, or even the same format. These were generally simple options, but as of IM version 5 the use of these processing features had become extensive, and more important than just image conversion.

As option multiplied and multiple options were used, the order of the options started producing weird and uncontrollable results. To users IM became known as unstable and uncontrollable when multiple image processing options was used, and it started to fall into disfavor.

IM version 6 saw the switch from a simple 'options' style, to a 'do it as you see it' style for image processing, and as a result, image processing abilities become stable, predictable and IM's ability became many orders of magnitude more complex.

As a result of this, "convert", is no longer so much about 'converting' images from one format to another, but as a command line API for accessing image processing functions, to create, and modify images in very complex ways, without needing a degree in image processing, or programming in some other computer language (such as Perl, PHP, or C).

Mogrify -- in-place batch processing

The "mogrify" command is in many ways like "convert" except it is designed to modify images in place. That is it's primary purpose is to read images (or animations), one file at a time, and modify them, before save the image back into the exact same filename the image was read from. Because of this...
Mogrify is dangerous, and can destroy the original image!

As such, before you do anything final, test "mogrify" with a separate copy of your images. Do not do use it on an original image.

Now while "mogrify" normally saves a modified image into the same filename, it has one special 'mode' in which is saves it to a different filename. The "mogrify" specific setting "-format", defines a different format and suffix to use when saving files.

As such a command like...

  mogrify    -format jpg  *.png

Will allow you to convert, or batch modify images, without destroying the original image. In this case converting all PNG files into JPEG files with that same filename but a different suffix. However be warned that if existing file with the same name will be over-written.

So let me re-iterate...
Think and check before you Mogrify
or you may find you just overwrote something you wanted to keep. As of IM v6.2.0 you can also use a new "-path" option to specify a different directory in which to output the processed images. This make it safer, however it will still overwrite any images of the same name that may already be in that directory.

As such you can create a thumbnail sub-directory using something like this...

  mkdir thumbnails
  mogrify  -path thumbnails -thumbnail 100x100  *

Before IM v6.3.4-3 the "-format" and "-path" settings were mutually exclusive. Upgrade if you need to use a different directory as well as a different image format for your output.

Due to the multi-image processing capability the "mogrify" command is a little more complicated, than that of "convert" as there are no specific input images, only a list of image images, which determine the output image filename to be used.

As some setting options are needed to be set before the first image is read in (for example (for example "-size", "-label" and "-density"), these options are processed and set before the first image is read in. After this each image is read in and the operators applied to them in command line order before the image is saved and the next image read in.

It is important to keep this in mind as if you change one of these settings later in the sequence you can make IM forget a previous setting.

For example..

  mogrify -format gif  -size 200x200  -pointsize 18 \
          -font Candice -gravity north  -annotate 0 "%f" \
          -font Ravie   -gravity Center -annotate 0 "%f" \
          -font Gecko   -gravity south  -annotate 0 "%f" \
          -size 100x64   xc:gold  xc:orange   xc:tomato
[IM Output] [IM Output] [IM Output]

As you can see the size of the above images generated was determined by the second "-size" setting with the first larger setting being ignored completely. On the other hand the font settings are set correct for each "-annotate" operation.

This added complexity means that it is probably a good idea to...
Mogrify images simply.

Do not attempt to do very long and complex "convert"-like operations in a batch operation using "mogrify", it will probably have 'setting' issues. If you are really wanting to do complex processing, write a shell/dos/perl script to use "convert" to process each image one at a time, or go to a ImageMagick API interface.

For examples of modifying lots of images using a script see Advanced ImageMagick Examples.

Just remember, "mogrify" is a dangerous command, and always should be thoroughly tested on copies of images, before putting into production.

Actually I also recommend that scripts include a quick 'tests' on things like "mogrify" to make sure the command does not break anything (due to version changes or differences in computer installations) before processing a very large collection of images. That is do a 'test case' and abort if it fails, before proceeding.

This is actually a good idea for any large scale image processing project, so as to protect users from unforeseen consequences. I do this myself in IM Examples, and it has saved me a lot of trouble, with new IM releases.

"Mogrify" will actually read all the input images into memory, then convert them one at a time. This means that in a large directory of large images, you could very easily run out of memory. If you plan to process a lot in images, you may be better of using a 'batch file' to convert them one at a time, or in groups.

As "mogrify" deals with a single list of multiple output images, it can not support the combining of multiple images together. As such Image List and Sequence Operators will not work. That is you can not perform operations like "-fx", "+swap", "-composite", "-append", "-flatten", and "-layers" in a "mogrify" command.

But that does not mean it is impossible to do image composition with multiple images.

Alpha Composition using "mogrify"

If you do want to do Alpha Composition multiple images using "mogrify", you can use "-draw" to perform image alpha composition. This allows you to specify the second image as part of its arguments, outside of the current image sequence.

For example, here I first make a copy of the original images I want to process using a special "cp_perl" script I found on the www. I then create temporary circle 'mask' image, which I then use to cut out a circle shape from all those images, using "mogrify" with a 'Dst_In' alpha composition method.

  cp_perl  's/^/mogrify_/'  eye.gif news.gif storm.gif tree.gif
  convert  -size 32x32 xc:none -draw 'circle 15.5,15.5 15.5,0'  circle.gif
  mogrify  -matte -draw 'image Dst_In 0,0 0,0 "circle.gif"'  mogrify_*.gif
[IM Output] [IM Output] [IM Output] [IM Output]  + [IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]

Note that any Alpha Composition method can be used in this way, but only with a constant 'source' or 'overlay' image being applied to all the images.

It also represents the only way to 'flatten' an image to a specific colored background, rather than just remove transparency (generally to black) using '+matte'. That can be done by using a 'Dst_Over' alpha composition method, to place that image 'under' the image being mogrified.

Also as "mogrify" will be reading the 'source' image multiple times, I suggest you use the special IM specific "MPC:" file format to reduce the overhead of decoding the image when reading it over and over. This format does not need to be parsed by IM as it will be mapped directly from disk into memory (for the same machine it was created on). This saves a lot of processing time, especially in dealing with for very large images.

Batch Processing Alternatives

If batch processing images using "mogrify" is not practical, especially if you are copying the images rather than modifying them in place, then it may be to use some other non-IM looping solutions. These include...

  # Use a simple shell loop, to process each of the images.
  mkdir thumbnails
  for $f in *.jpg
  do   convert $f -thumbnail 200x90 thumbnails/$f.gif
  done

  # Use find to substitute filenames into a 'convert' command
  # This also provides the ability to recurse though directories by removing
  # the -prune option, as well as doing other file checks (like image type,
  # or the disk space used by an image).
  find * -prune -name '*.jpg' \
         -exec  convert '{}' -thumbnail 200x90 thumbnails/'{}'.gif \;

  # Use xargs -- with a shell wrapper to put the argument into a variable
  # This can be combined with either "find" or "ls" to list filenames.
  ls *.jpg | xargs -n1 sh -c 'convert $0 -thumbnail 200x90 thumbnails/$0.gif'

  # An alternative method on linux (rather than plain unix)
  # This does not need a shell to handle the argument.
  ls *.jpg | xargs  -I FILE   convert FILE -thumbnail 200x90 th_FILE.gif

And so on.

If it starts to get more complicated than this, it may be time to go to a shell script, or API program, to read in multiple images, gather information, calculate appropriate arguments, and process the images.

WARNING: "mogrify", and all other IM commands will also expand all filename containing shell meta-characters such as '*' and '?'. This is done to allow the use of these meta-characters on the old DOS command line shell. However this could cause a bug, repeated mogrify execution, or possibly even a 'hack' from a some evil source. Caution is advised, especially with using 'find'.

Composite -- overlaying images in special ways

The "composite" command is designed specifically for alpha compositing (overlaying) two images together in various ways. This includes limiting the area in which images are combined together, though the use of a third masking image.

The "composite" command also provides access to some alpha composition modes not available elsewhere in IM. For example "-dissolve", "-blend", and "-watermark" image composition. If any of these arguments are given, they will override any "-compose" setting that was (or will be) given for that command.

Note also that the "-tile" setting also works differently to that of either "convert" or "montage" and "display". In "composite" this will cause the overlaid image to be tiled across the whole of the background image.

While these special features makes "composite" a useful command, the general alpha compositing operation is now also available for use in the "convert" command. (For details see Alpha Composition in IM).

For a summary of multiple different ways of overlaying two or more images together see the examples in Layers of Multiple Images.

For more information on the method by which two images can be merged together see the Alpha Compositing examples page.

The overlay limiting or 'Masking' abilities is also detailed in the above examples page in Using a Compose Mask to Limit the Composed Area.

Montage -- generating arrays of thumbnails

The special IM image indexing command "montage" also followed the same 'do it as you see it' style of command line structure, as "convert".

The only difference is that when the end of the command is reached (other that the fine output image filename argument), "montage" will start to process the image sequence into a thumbnail image index page(s), according to the settings that are currently set.

This makes "montage" much more versatile than it was in IM version 5, as you can now process the images just as you would in "convert", then set all the "montage" settings you want, and let it finish the job.

For more details about "montage" see Montage, Arrays of Thumbnails.

identify -- Print the details of images, that IM sees

The "identify" command is designed to return information about an images in a simple and useful way. By default it outputs a simple compact summery, detailing the images name, file format, image size, virtual canvas size and offset, color depth, internal format type, and if known the original size of the image on disk in human terms.

For example...

  identify  tree.gif
[IM Text]

Not that the '8c' in the above result is not the number of colors within this image (which is actually 6 not 8), but the 'pseudocolor' palette size (see later example for actual number of colors). Also note that the image 'virtual canvas' is the same size as the actual image with a zero offset, meaning it is currently not being used.

Adding a -verbose, Operational Control, will produce as much information about the image that IM knows about or can easily calculate. This includes color statistics, color counts, profile information, internal image save type of the image, etc. etc..

You ask IM it only read basic information about an image using a special "-ping" option. This causes identify to attempt to only read enough of the image file to determine simple image information, such as size, without trying to read the whole image into memory. Most image file format will allow you to do this, but not all. This is the biggest advantage of "identify" over the many "convert" image information output operators. (See Ping, Operational Control below). For example.

  identify -ping tree.gif
[IM Text]

Specific information can be obtained and output in specific ways by using the "-format" setting, and IM special percent ('%') escapes to output Image Properties.

For example you can just extract a count of the number of colors within an image.

  identify -format '%k' tree.gif
[IM Text]

You you can format the image information in a form that is directly usable in a web pages. You don't even need to limit it to just a single image either! Note the output difference between a '%i' and a '%f' in the results generated.

  echo '<HTML><BODY><CENTER>'
  echo '<H1>  Some Image Thumbnails  </H1>'
  echo ''

  identify -ping -format '<IMG SRC="%i" ALT="%f" WIDTH=%w HEIGHT=%h>\n' \
           ../photo_store/anthony_*  ../photo_store/*_tn.gif \
           tree.gif   storm.gif   ../images/logo.gif

  echo '</CENTER></BODY></HTML>'
[IM Text]

You can see the result of the above output as a HTML Web Page showing the images. Of course if you want to do other things like link the tags to a larger image, you may need a more complex thumbnail handling script (See discussion about HTML Thumbnail Pages).

Even some floating point mathematics using FX Expressions is perfectly valid.

  identify -ping -format 'double_width=%[fx:w*2] PI=%[fx:atan(1)*4]' tree.gif
[IM Text]

Note that the math does not even need to be related to the image itself, allowing you to use IM as a simple floating point calculator for us within your scripts.

As of IM v6.2.4 you can also produce identify output from the "convert" command, either as the final output result, or even in the middle of a longer image processing sequence. See the special "info:" output file format for details.

Some extra notes about identify (still to be formated)...
  * Normally IM reads in the image into its own data format, using various
    image library APIs and delegate programs, before outputting the results it
    sees using identify.  That is "identify" analyzes the full image/data
    content, not the specific file format the image is using for storage.

    This is important as there can be very specific aspects of specific
    file formats that "identify" will not report on.  For example while
    it lists the contents of a GIF image color table for each image
    present (multiple images are possible), it will not tell you if all
    the images in the file share the same color table or not.

    If you need  specific info about specific image file format, it may
    be better to use a tool designed specifically for that format.  For
    example "giftrans" for the GIF file format, and "jpegtrans" for
    the JPEG file format.

  * Note that if image has more that 1024 color no histogram or color tables
    will be included in the verbose output. To force the generation of this
    info use 'histogram:' to generate it as a image comment. See histogram:").

  * The identify program returns a non-zero exit status if a corrupted image
    is encountered and you add a
    -regard-warnings, Operational
    Control.

    error=`identify -regard-warnings image 2>&1 >/dev/null;`
    if [ $? -eq 0 ]; then
      echo "The image is good"
    else
      echo "The image is corrupt or known format"
      echo "$error"
    fi
Scripted readers of any form of "identify" output, should do so in a case in-sensitive way, for backward compatibility between different versions of ImageMagick.

compare -- Look for Differences

All current information on this is on the Image Comparison Page section of IM Examples.

display -- Slideshows of Images

The "display" program is designed to display a image, or sequence of images in the form of a looped slideshow. It is not designed for a carefully orchestrated and timed animation of images, for that use the "animate" command.

Each image will be displayed in a window sized appropriately for the image, unless other options (like window "-geometry", see below) override this behaviour. The image will also generally be displayed on a checkerboard background so as to show the effects of any transparency the image may have (see below).

Remember this is NOT designed for the display of an animation, but mean as a slideshow of actual images. As such some caution may be needed when using display in a scripting program.

Image Display Time

By default a delay of approximately 2 seconds is used on top of whatever delay the user specifies using the "-delay" setting. However you can make it wait for user input (spacebar) by using the option "-delay 0". However those defaults can be override by the images themselves, depending on there file format. As such animation formats like GIF and MIFF could result in either a pause, or a 2 second plus the images meta-data delay setting. It is thus recommended that you always set a "-delay" as appropriate (remember "-delay 5x1" will delay 5+2 or about 7 seconds).

The same goes for the "-loop" setting. By default "display" loops forever ("-loop 0") but image formats like MIFF or GIF can override this so as to cause it to exit after last image in the loop.

Note that "display" will not handle any GIF Animation Settings so frames are not disposed of, and virtual canvas sizes and offsets are ignored. In other words you will see the raw partial images in a GIF animation, not the correctly overlaid image. It does provide a "-coalesce" option to clean up such animations for display purposes.

Transparency Handling

Images containing a full alpha channel (EG PNG and MIFF formats) will be overlaid onto a 'checkerboard' background pattern, so as to let you see the effects of any semi-transparency, such as shadow effects.

You can change that by selecting a different background with "-texture" such as...

  display -texture granite: test.png

  display -texture xc:black test.png

Images with a palette (or boolean) transparency, such as GIF and PNG8 formats, is displayed with a the current 'transparent color' that was used to represent transparency in the color table. That is a generally random color may be used (typically black) rather than the default checkerboard pattern. This could be regarded as a bug, though technically it isn't.

However if you like display to handle such images in the same way as other images containing transparency information, you can remove the palette meta-data before feeding the image to "display" using the following commands to change the internal style for the image output format.

  convert image.gif -type truecolormatte miff:- | display -

Alternatively, just about any operation that modifies the image being displayed will also remove the existing palette meta-data. As such some "display" options can be used to remove the palette. For example using "-coalesce".

  display -coalesce image.gif

This has the added bonus of cleaning up GIF animation optimizations that may be present. Though for multiple, unrelated images it could have other undesirable side effects.

Yes these methods are clumsy, but they work.

Display Output Size

Display will not scale an image to fit it to the X window display. The window size will be adjusted to fit each image, unless set using the "-geometry" setting. That setting can also be used to fix the windows position on the X window display.

Images which are larger that the screen, will also not be resized, but will overflow the screen, display will however also provide a 'scroll window' to let the user slide around the image.

This can be painful when viewing a modern high resolution digital photo.

To limit display to say a 800x600 pixel area (only resize smaller, never larger), use...

  display -resize 800x600\> photo.jpg

For JPG images you can speed up the image read by using a "-size" setting

  display -size 1600x1200 -thumbnail 800x600\> photo.jpg

If you want to know your X windows display size use "xdpyinfo" though that is not strictly IM specific.

  xdpyinfo | grep dimensions:

Note you should use a slightly smaller size than the returned display size to allow for window decorations.

If the image is from a modern digital camera you can also use "-auto-orient" to correct the camera rotation of the displayed image, using the EXIF meta-data in the image file format.

If you don't want menus, you can turn them off using the "-immutable" setting to "display", so it knows not to allow editing.

Scripted use of Display

With all these in mind, the following is my recommendation for using "display" to display results from a complex shell script...

  display -delay 0 -loop 1 -coalesce -resize 800x600\>   some_random_image

Display Alternative

An alternative display method (other than using "animate", see next) is to use the simpler "x:" output image format (See display output format).

  convert image.png x:

This method does not provide a backdrop window, menu options, or other controls. It just simply displays the images one image at a time.

However be warned that displaying images using this method will only allow BOOLEAN transparency, due to the old limitations of X window displays. That it is the transparent parts will be either completely transparent or opaque. As such edges of some images will look bad, and semi-transparent shadows may not be shown correctly. Better to use "display" when transparency is involved.

If you do want to just simple 'display' the resulting image the special 'show:' or 'win:' output Spawning Delegate will do the same thing by runing the "display" command on the output image, and exiting.

  convert image.png show:

None of these techniques is recommended when the image contains transparency.

animate -- Show an animation of images

In many ways "animate" and "display" are extremely similar.

However "display" only shows the images in the given image file 'as-is' without change, adding an minimal 2 second pause between each frame for user input.

"animate" on the other hand will apply any GIF Animation Settings that are saved with the image, and only display each image according to its 'time delay' settings, looping back to the start to repeat the animation. In other words "animate" 'animates' animation formats properly where "display" does not.

However because of this, the virtual canvas of the first image will control the output image size, and other image will be overlaid into that image area.

Of course as the images are animated, you do have a fine control of the image display timing, using options such as "-delay". The command also has an extra argument "-pause" to add an extra pause at the end of the animation loop, beyond whatever the final frames "-delay" setting specifies.

For example you can use "animate" to generate a Flicker Comparison of two very similar images, using something like..

  convert image1.png image2.png -scale 400% miff:- |\
     animate -delay 50 -loop 0 -

I have written a script to take advantage of this method called "flicker_cmp", and find it extremely useful to pickup very subtle changes in pixel intensity that I would otherwise miss.

stream -- pipeline processing of massive images

"stream" is a special program that is designed to handle extracting a portion of a very large image file format. It is the only such program within ImageMagick, all others read the images completely into memory before processing (the exception is JPEG images via the "-size", as this is an option provided by the JPEG delegate library).

However "stream" will only output the raw color bytes of the image (RAW format) as defined by the image depth.

You can select a portion of the image with the "-extract" setting. And you can specify the depth of the raw bytes with "-depth" setting. And finally, you can select which color channels to extract using the "-channel" option.

For more information and examples see Really Massive Image Handling.

import -- read images from the on screen display

The "import" command is a special program that can be used to grab and extract images from an X windows display. For example lets get it to grab and print a window you select from your display...

  import -page A4 -gravity center ps:- | lpr

It is actually rarely used as the special file format "X:" also provides exactly the same functionality from within the convert command.

The only difference between the two is that "import" has more X window specific settings than the "X:" format, such as specifying the display, screen, and/or window ID, the image is to be grabbed from.

Other options include controls display 'beeping' and repeated snapshots.

If no specific window is specified, the mouse can be used to select what parts of the display the user wants to grab as an image.

Other options allow you to avoid human interaction with the mouse by grabbing the whole screen ("-window root"), or a specific window (given a window title, or a X window ID, which you can find using the X window utility "xwininfo". You can also cut down the area of the selected window using "-extract".

See also the special input format, "X:" as an alternative to using "import".

    Note to import from the Windows clipboard use
      convert clipboard:myimage image.png
    and not "import"

conjure -- IM experimental scripting language

Was originally designed to allow scripted Imagemagick use, with the use of multiple image lists, but the improvements made to IM v6 "convert" has seen this experimental API fall into disuse.

It is an XML based language. Though if you want XML, SVG may be better for your needs.

In my opinion, using the "conjure" script is probably better and easier when dealing with multiple image sequences. And is being used, though not very widely, due to lack of examples and support by users.


Image Sequences or Lists...

One of the most important points to remember with ImageMagick, and one that confuses both new users and experienced users, is that...

ImageMagick works with Ordered Lists of Images, not single images

That is IM deals not with just one image, but potentially a ordered list of images, be they separate individual images, a set of images that layer on top of each other, or the frames of an animation.

Also in general all image operators will be applied to all the images in a sequence. This is true whether you are using the command line, a higher level programming library such as 'MagickWand', or the lower level programming APIs. This was also true in previous versions of IM.

As such if you use a "-draw" operator, it will not only draw on the last image in the sequence, as many new users would assume, but it will draw onto all the images in the current image sequence, and does so, one image at a time.

Image Layering Operators, such as "-coalesce" and "-layers" will replace each image in the sequence with a new image modified according to the other images in the sequence. It may even add or remove extra images!

Also Image List Operators, like "-append", "-mosaic", and "-fx", will replace ALL the images in the current image sequence with the resulting combined image. That is it will destroy all the source images that were in memory, unless a "-clone" has been made (see Image Sequence Operators below).

Finally when a new image is read in or created, IM only adds that new image to the end of the current image sequence (which always exists). Some formats (like GIF) may actually add multiple images to the current image sequence, unless "[index]" option is added to the input filename, to limit what is read in.

When saving images, IM will save the whole image sequence that is in memory at the time of writing. If image format allows it IM will write ALL the images into a single file. If the format does NOT allow multiple images (for example JPEG), it will write the images into separate files (See Writing a Multi-Image Sequence below).

Parenthesis -- processing images 'on-the-side'

With the formalization of the command line options, the processing order is now exactly predictable, and it has also become possible to add parenthesis (or brackets) to the image processing. This has been a desired feature by IM users for a long time, and allows you to do things never before possible in a single command.

The opening bracket '(' will in effect start a new image sequence, that all enclosed operators will work on. The matching close bracket ')' will then add the resulting image sequence (which may be more than one image, or none at all) to the end of the previous image sequence.

In other words, using parenthesis means...
"I need to do a bit of work in a separate image sequence
before adding the results to the end of previous sequence."

It allows you to work on a sub-set of images, like a scratch pad, than add the result back into the main image sequence without effecting the images you have already previously read in or have been working on.

Let's look at some simple examples...

  convert   eye.gif  storm.gif  -negate  +append  cmd_negate.gif
[IM Output]

As you can see the "-negate" operator, color negated both images, as both were in the current image sequence in memory at that time.

But by adding parenthesis we can limit the negation to just the second image...

  convert   eye.gif \(  storm.gif  -negate \) +append  cmd_bracket.gif
[IM Output]

Because the "storm.gif" image is read into a separate image sequence to that of the first image (generated by the "(" image sequence operator), it can be negated without affecting the first image. Then we can add the result to the main image sequence (that is the ")" operator), before appending the two images together as before.

Parenthesis must be given as a separate argument. That is you must separate them from the other arguments by spaces. You can not add them hard up against neighbouring arguments. In other words in the IM command line argument " \(+clone " is wrong, while " \( +clone " is correct.

Also in the last example that I needed to put a backslash '\' before the parenthesis. That is because when using IM on a UNIX (linux) machine, parenthesis has special meaning to the command line shell. As such I need to escape, or quote the bracket symbols, when I use them.

Windows DOS scripts do not require parenthesis to be escaped with backslash. See Windows DOS Scripts for this and other differences to linux scripting.

Parenthesis also make it possible to do something not previously possible to do in a single "convert" command. Generating arrays of images!

  convert  eye.gif news.gif  +append \
         \( storm.gif tree.gif +append \)   -append  cmd_array.gif
[IM Output]

Arrays like this were of course possible using "montage" (see Montage Concatenation Mode), But using a separate command makes image processing scripts more complex.

Of course if you like to make the command look more array like itself, you are free to add some extra parenthesis.


  convert \( eye.gif    news.gif  +append \) \
          \( storm.gif  tree.gif  +append \) \
          -append  cmd_array2.gif
[IM Output]

The extra parenthesis aren't needed, and do add a tiny amount of extra work to IM's internal processing, but it does make it clear what the command is doing by separating the processing steps. It may also be easier for image processing scripts to generate.

Parenthesis and Settings

Option 'settings' are not affected by parenthesis, and will continue across the parenthesis image operators, until the setting is changed or turned off.

For example...

  convert -pointsize 24 \
          -font Candice label:Outside \
          \(              label:Inside \
             -font Gecko  label:Inside \) \
          label:Outside       -append   cmd_settings.gif
[IM Output]

Note how the first "-font Candice" setting is NOT reset back to its default setting inside the parenthesis, while the second "-font Gecko" is not replaced by the original font setting when you leave parenthesis.

In other words...
Parenthesis only start and end a separate Image Sequence.
They do not limit settings, only the sequence of images to which operators will be applied to.

As of IM v6.4.1-4 the new operational control option "-respect-parenthesis" can override this behaviour.

When given at the start of a IM command, it will cause parenthesis to also save and retrieve the previous settings that have been given. That means any settings given within parenthesis, will only remain set, until the end of the parenthesis.

For example...

  convert -respect-parenthesis   -pointsize 24 \
          -font Candice label:Outside \
          \(              label:Inside \
             -font Gecko  label:Inside \) \
          label:Outside       -append   cmd_settings2.gif
[IM Output]

As you can see, when the parenthesis ended, the font setting was restored to the previous 'Candice' font, instead of the 'Gecko' font that was set within the parenthesis.

This can be most useful when you have to change a lot of setting, for just a short time...

  convert -respect-parenthesis \
          -font Arial   label:"This is a line of plain text." \
          \( -font Candice -pointsize 16 -fill red -undercolor lightblue \
              label:"A line using a lot of different settings." \) \
          label:"Text is back to normal -- like Magick\!" \
          -append  cmd_settings_lots.gif
[IM Output]

Image Sequence Operations

With the stronger emphasis by IM on image sequences, especially within parenthesis, it is no surprise that a set of new image operators have been provided to manipulate the image sequences.

The arguments to these operators are numbers indexing the image sequence, starting with zero ('0') for the first image, and one ('1') for the second image, and so on. However if you give a negative index, the images are referenced from the end (last image added) of the image sequence. That is a index of '-1' is the last image in the current image sequence (generally the last image read or created), '-2' for the second last and so on.

-delete {index}

The "-delete" sequence operator is the simplest of the new image sequence operators, it just deletes an image from the image sequence.

  convert font_[0-3].gif -delete 1 +append  seq_delete.gif
[IM Output]

The 'plus' form of the operator, "+delete" does not take an argument, and just deletes the last image in the current image sequence.

The "-delete" operator will also accept a comma separated list of numbers, or a number range to be deleted.

  convert font_[0-7].gif -delete 1-4,6 +append  seq_delete2.gif
[IM Output]

Or delete everything (and add a new image)...

  convert font_[0-7].gif -delete 0--1  tree.gif seq_delete3.gif
[IM Output]

The '0--1' argument means delete images from first image (index 0) to the last image (index -1). In other words ALL images in the current image sequence. The tree image was then added to give IM a actual result, rather than a 'no image' type error.

If a image index does not exist, or a number range is reversed, "-delete" will silently ignore that specific image deletion. The argument '-25' will attempt to delete the last 25th image in the image sequence, but will silently do nothing if less than 25 images are present. As such you can generate a rolling animation of 24 images using a sequence like...

  convert animation.gif  new_frame.gif  -delete -25  animation_new.gif

However the above will only roll the last 24 images, if more that 25 images were present the first few images are left alone.

As of IM v6.3.4 "-delete" will not delete images that result in the numbered range being reversed.

That means you can do something like this.

  convert animation.gif  new_frame.gif  -delete 0--25  animation_new.gif

Which will delete all images between the first (0) to the last 25th image. That leaves just the last 24 images in the list. If only 24 or less images are present, the given range of images to be deleted will be effectively reversed, and the "-delete" operator will not delete anything.

-insert {index}

The "-insert" operation is sort of the opposite of "-delete". It will take the last image in the current image sequence and insert so that it is positioned at the given index.

  convert font_[0-3].gif tree.gif -insert 1 +append seq_insert.gif
[IM Output]

You can think if the insert index as the number of images that should appear before the point where the image was inserted.

Of course the image that was at that index (and all the images after it), will of course be bumped up into the next index position to make room for the new image.

If a negative index position is used, the insert position is calculated after the image being inserted is removed from the end of the sequence. That is it will act as if the image being inserted was not part of the original image sequence. As such "-insert -2" will 'roll' the last three images, placing two images between the newly inserted image and the end of the image sequence.

  convert font_[0-3].gif tree.gif -insert -2 +append seq_insert2.gif
[IM Output]

The plus form "+insert" will move the last image to the front of the image sequence (index 0), effectively rolling the whole image sequence.

  convert font_[0-3].gif tree.gif +insert +append seq_insert3.gif
[IM Output]

To do the inverse of the above (move an image to the end of the image sequence), can be done by first using "-clone" (surrounded by parenthesis, see later) to copy the image, then use "-delete" to delete the original image.


  convert font_[0-3].gif   \( -clone 2 \) -delete 2 \
          +append   seq_insert_inverse.gif
[IM Output]

This is actually very fast, as "-clone" only clones the image meta-data, and not the image data itself. In a clone the data is only copied when it is also modified.

-swap {index},{index}

Simply put "-swap", will swap the positions of two images in the current image sequence. For example "-swap 0,2" will swap the first and the third images in the current image sequence.

  convert font_[0-3].gif  -swap 0,2  +append  seq_swap.gif
[IM Output]

The plus form of this option "+swap" will swap the last two images in the current image sequence. In other words, it is equivalent to "-swap -2,-1".

  convert font_[0-3].gif  +swap  +append  seq_swap2.gif
[IM Output]

Probably the most common use of this operator is to swap two images before being used by a image layering operator such as "-composite", "-flatten", "-append", or "-fx".

  convert tree.gif  frame.gif   +swap \
          -gravity center  -composite   framed_tree.gif
[IM Output]

As of IM v6.4 a "-swap" with a single number will swap the last image with the number given. That is "-swap 1" is equivalent to a "-swap -1,1".

  convert font_[0-3].gif  -swap 1  +append  seq_swap3.gif
[IM Output]

-reverse

The "-reverse" operator (added to IM 6.3.4) will quite simply reverse the order of the whole image sequence.

  convert font_[0-3].gif -reverse  +append seq_reverse.gif
[IM Output]

-clone {index}|{index_range},...

This image sequence operator is a little different. Given an image sequence number "-clone" will make a copy of an image that has been saved by the 'open bracket' or 'parenthesis' operator. That is...

Clone should only be used within parenthesis

The reason for this is that it allows you to extract a copy of an image from the last saved image sequence, so you can process it further. For example.

  convert font_[0-2].gif \( -clone 1 -rotate 90 \) +append  seq_clone.gif
[IM Output]

If you only want to make a copy of the image, just surround the option by parenthesis, and let the image be added to the end of the image sequence.

The 'plus' argument-less form "+clone" will just make a copy of the last image of the saved image sequence so that you can process it further

  convert font_[0-2].gif \( +clone -flip \) +append  seq_clone2.gif
[IM Output]

As of the release of version 6.2.2 "-clone" operator will take a comma separated list of images, or a range of indexes of the form '{index}-{index}'.

  convert font_[0-2].gif \( -clone 1-2 \) +append  seq_clone_range.gif
[IM Output]

Of course negative indexes still behave just as you would expect. For example to duplicate the whole image sequence you can specify it using numbers '0' (first image) and '-1' (last image), that is by using the range '0--1'. It may look strange but it makes sense and works fine.

  convert font_[0-2].gif \( -clone 0--1 \) +append  seq_clone_all.gif
[IM Output]

When you use a comma separated list of indexes, the images are extracted in that order you specify.

  convert font_[0-2].gif \( -clone 2,0,1 \) +append  seq_clone_list.gif
[IM Output]

If the images in a range are reversed (after negative indexes are converted to a actual image index), the extracted images is also reversed, as part of the process.

  convert font_[0-2].gif \( -clone 2-0 \) +append  seq_clone_reversed.gif
[IM Output]

This makes it easy to create a 'patrol-cycle' type of animation sequence without needing to first clone the images, then separately reverse the order.

  convert font_[0-5].gif \( -clone -2-1 \) \
          -set delay 50 -set dispose previous -loop 0  seq_reverse_anim.gif
[IM Output]

Note that I did not copy the whole sequence, but skipped copying the very first (0) and last (-1) image, making the sequence -2 to 1.

Note that "-clone" without the use of parenthesis will just copy images from the current image sequence and directly append them. However this is not its intended use and is to be discouraged as it will produce a different result if you later surround that set of operations by parenthesis.

The MPR: Image Memory Register, can also be used to clone images and was available in IM v5. It is actually still a useful method for cloning and storing a whole image sequence (of unknown length) for later use, and not just a single individual images as the above image sequence operators do.

Combining Image Sequence Operations

Using these operators, you can extract a copy of a specific image, modify it, and return that image back where you got it from.

For example, here I make a "-clone" of the 2rd image (image index '1'), rotate the images colors from blue to red, then replace the original image with the modified one by first "-delete" it and "-insert" the new one.


  convert font_[0-3].gif  \( -clone 1  -modulate 100,100,166 \) \
          -delete 1  -insert 1    +append seq_update_1.gif
[IM Output]

Another way that seems to have become more common is to "-swap" to replace the original image, then "+delete" the old image that is now on the end. This only requires you to give the image position twice, instead of three times. Once to extract, and once to replace.

  convert font_[0-3].gif  \( -clone 2  -modulate 100,100,166 \) \
          -swap 2  +delete     +append seq_update_2.gif
[IM Output]

This means you can now create temporary images, and keep them in memory, for further processing, without needing to save them out to disk or a memory register.

For example, here I go though a whole complex processing sequence to generate a red button on a black background. Each line of the convert command generates a new image, except the last line where I just appended all the working images together.

  convert -size 30x30 xc:black -fill white  -draw 'circle 15,15 5,15' \
          \( +clone -shade 110x90 -normalize -negate +matte \) \
          \( +clone -clone -2 -compose Plus -composite \) \
          \( -clone 0 -shade 110x50 -normalize +matte \) \
          \( +clone -gamma 1,0,0 \) \
          \( -clone 2  +clone  -compose Multiply -composite \) \
          -append  seq_process_fx.gif
[IM Output]

This technique lets you follow what each line of the very complex command produced, and allows for easier debugging of each step in of a process.

The above only uses the initial image's size and shape to generate the initial shape of the button, so you are free to use any shape or image you like! The rest of the command will process it just like before.

As you can see I used the "-append" image list operator to join all the images together so I can see want is happening and debug the IM command. Alternatively you can pipe the image list into a "display" or "montage" command to view the results.

Of course you would normally delete the temporary working images when finished. If you have a lot of such temporary images, you can also just "-write" the one final image, then junk the rest using the the "null:" image file format. See Null Image format for an example of this.

Alternatively you can delete or remove the working images as you process and finish using them, in which case you often don't have much to clean up when finished.

For example, here I follow the same image process I used above, to process a fancy label. This time however I merged many operations together into common image sequences. Also we don't "-clone" the images as much, and "-composite" merges images to leave just the result, there is actually very few intermediate images that needs to be specifically deleted .

  convert -font Ravie -pointsize 48 -background black -fill white \
          label:'IM' -bordercolor black -border 5  seq_label.gif
  convert seq_label.gif +matte \
          \( +clone  -shade 110x90 -normalize -negate \
             +clone  -compose Plus -composite \) \
          \( -clone 0 -shade 110x50 -normalize -gamma 1,0,0 -matte \) \
          -delete 0 +swap  -compose Multiply -composite  seq_button.gif
[IM Output] [IM Output]

The problem with this technique is that debugging the IM command becomes more difficult, though not impossible. It is still faster than using lots of temporary files to hold your working images.

The ability of ImageMagick, to process any image, in a standard, programmed, and automated way, regardless of the input image, such as we did above, is what makes IM such a powerful tool. You can script up a very complex operation, then apply it to multiple images, or in this case simple shape images. Image sequence operators, and parenthesis just made IM an order of magnitude more powerful, allowing you to write more complex image manipulation programs, with fewer commands.

For other examples of scripting a complex images process together see the Advanced Image Processing examples page.


Image Attributes and Settings

Under Construction

There are a lot of different types of settings and data within ImageMagick and it can be very confusing to users about what does what, and how.

For example their are settings too... What makes this worse is that often a source for a particular setting can come from a number of places, and can influence each other. Also many of the settings are automatically assigned, and updated from the act of reading in images, or just modifying them. It isn't any wonder than things can get confusing.

 * Settings that get saved meta-data attributes into images that are created
   or read in.  These can differ from specific image to specific image.
   EG:  -page  -label  -comment  -delay  -density
      (and + versions that turn them off)

   Their are also specialized operators that will change these specific image
   settings.   EG:  -set   -repage   +repage

   Though many other operators also change the meta-data saved with specific
   images as part of its operation. For example, -crop and -transform can
   adjust an images saved virtual canvas size and offset on that canvas.
   And coalesce and -layer operators can change an images GIF -dispose and
   time -delay attributes.

 * Some settings effect the way an image is saved to disk, or the meta-data
   saved with the image.  This includes
     -loop  -define  -compression  -quality  -depth
     -density  -background

ASIDE:
   The -set operator vs the -define setting.  These are very similar but
   are used and applied in very different ways.

    -set
        Operation that attaches/changes a specific image meta-data to image in
        memory.  Images often load these meta-data settings with the image
        itself.

        Specific Image meta-data
          -set comment ...
          -set label ...
          -set page ...
        Special Operator specific settings for special handling
          -set option:distort:zoom 2

        Different images can have different settings, producing different
        results.

    -define
        Is a table of global IM settings that effect specific deep operations,
        often special image format libraries. They are especially relevant to
        I/O operations of images, such as JPEG, PNG and TIFF.

        For example...
          -define jpeg:preserve-settings
          -define jpeg:optimize-coding=false
        See Writing JPEG Images

        The equal sign is required, (unlike -set)

        This are global definitions and are not directly attached to specific
        images, though may be inherited by images created or read in later.

        TO BE RE-VERIFIED
        For example you can
           -define distort:zoom=2
        with will add the "-set option:distort:zoom=2" special settings to any
        image that is created or read in, after that -define.


 * Operation effecting settings are not attached to specific images, but get
   used as they are currently set at the time the using operation is applied.
   EG: -fill  -background  -bordercolor -strokecolor -mattecolor
       -quantize  +dither -channels  -size  -gravity  -units
       -density  -pointsize  -depth

   Some of these however can be turned off, (using a + version) which
   causes the operator to retrieve the setting from image meta-data
   (eg: +background falls back to the original images meta-data in present)
   or some default value (eg +gravity falls back to 'None or NorthWest').

   A few of these also get saved with images when written. Specifically
   the GIF format will save an the -background and -bordercolor as part of the
   images attributes, however these are normally ignored by programs which
   read these images.

You may have notices that some setting are used in multiple places.
for example  -density
  * used in reading in many vector format images like
    Postscript, PDF, and WMF image formats.
  * also in special image generators such as label: caption: and text:
  * used as part of font drawing in -annotate -draw and -polaroid  operators.
  * And finally some formats save the density or resolution as part
    of the the image file format. For example postscript wrapped raster
    images, JPEG, and TIFF.

Is it any wonder then why settings can be so confusing.

Setting/Changing Image Attributes

Image Meta-data settings are generally controlled in two ways. A direct changing of the image metadata as they are read in. Or a modification of that meta-data once the image has been created in memory.

For example "-label 'string'" will set the comment in every image that is read in or created after that setting has been set. However "-set label 'string'" will change the 'label' meta-data of all images that are in the current image sequence.

The reason for the two methods is a historical backward compatibility and convenience. Basically "-label" has traditionally been set BEFORE the image it is applied to has been read in. Also it only effects images that are read in while it is set.

FUTURE: Move montage list examples here. 

  convert -label one  image_one.png \
          -label two  image_two.png     output_image_list

The "-set" operator will however changes ALL the images that are in the current image sequence, including ones previously read in. Thus to use it you must use parenthesis to limit what image you are applying the option to.

  convert \( image_one.png -set label one \) \
          \( image_two.png -set label two \)  output_image_list

You can un-define the setting using "+label", in which case the label meta-data will come from the image itself, if present. If the image doesn't have a label, IM falls back to a logical default, in this case the empty string.

This same idea also goes for all the other option that set image meta-data on input. This includes... "-page", "-dispose", "-delay", "-comment". The virtual canvas size and image offset setting (page) however also has a special 'set' operator "-repage".

For example here I use both attribute setting methods to create a Montage...

  montage -label Read   eye.gif  \
          -label News   news.gif  \
          \( storm.gif -set label Storm \) \
          \( tree.gif  -set label Shelter \) \
          -tile x1  -frame 5  -geometry '60x60+2+2>' montage_label.jpg
[IM Output]

Or in creating Animations from individual images...

  convert -delay 100 -dispose Background \
            -page 100x100+5+10  eye.gif  \
            -page +35+30        news.gif  \
            \( storm.gif  -set page +62+50 \) \
            \( tree.gif   -set page +10+55 \) \
          -loop 0  animation_page.gif
[IM Output]

As you can see the traditional (non-set) method is simpler when creating multiple image sequences from separate image files. But "-set" is the better way to change a image that has already been read into memory, or was created from image processing.

For example to change the image offset of the third image (image index '2') in the last example...

  convert animation_page.gif \
          \( -clone 2 -set page +55+10 \) -swap 2  +delete \
          animation_mod.gif
[IM Output]

For a more extreme example of extracting and modifying individual images in a image sequence see Frame by Frame Modification of an Animation.

Alternative to "-set"...

In IM there is only one other way of changing an images attribute once it is already in memory, and that is by having IM re-create that image from a in-memory image register (see the special "mpr:" 'file' type).

For example here we take an image with a 'Bad' comment, that is in memory, and replace the comment with a 'Good' one...

  convert -comment Bad  input_image \
          -write mpr:register +delete \
          -comment Good   mpr:register    output_image
  identify -format "image comment = %c" image

This works, but is extremely awkward and painful to use, especially when dealing with multiple images such as an animation. In fact this is the only way to change meta-data in images in IM version 5.

Page, Repage, and Image Offset Control on the Virtual Canvas

The 'page' or 'virtual canvas' settings primary purpose within IM is to define how a the 'real' part of an image, (the part that actually contains color pixel data), fits in a larger context of a 'canvas'. This is especially important when multiple images are involved and need to be positioned relative to each other for Layers of Multiple Images and in GIF Animations.

It is also used, (and hence its name of the term 'page') to define where an image fits on a larger physical pice of paper or 'page', in Postscript or in generating image of a 'page' of Text.

While it is most often used for Layers of Multiple Images and in GIF Animations, it is also involved with remembering the original positions of images when Cropping, and Trimming Images, as well in Multi-Image Sequence Alpha Composition, and in General Image Distortions.

Now the attribute defines two separate parts a 'virtual canvas' or area, defining a larger space in which the image exists, and the 'offset' or location within that 'canvas' where the actual image is positioned.

Under Construction

Controlling an images 'page' or 'virtual canvas' meta-data...

As discussed above -page is a global setting for image being read or created,
while -set page will specifically assign a new page or virtual canvas
attribute to an existing image.  However a third special option has also been
provided that adjusts the image virtual in very specific ways.

The -repage operator will do the following, in response to the the argument
given.
  +repage
    Reset the image virtual canvas to the actual image itself.  That is just
    clear any virtual canvas that the image may have.  This often important
    after applying the image sub-diving operators -crop and -trim.
    It is especially important in removing virtual canvas size and offsets
    before saving to the GIF or PNG image file formats, as many browsers use
    the canvas/offset information as part of the image display.

  -repage WxH
    change the existing images virtual canvas size, but do not reset the image
    position on that canvas.  Note both -page and -set page will reset the
    images location to +0+0.

  -repage +X+Y
    Just move the image on the virtual canvas to this absolute location
    without changing the images canvas size

  -repage +X+Y\!
    Do a relative move of the image on the virtual canvas by adding the given
    numbers (positive or negative) to the images existing offset position.

  -repage 0x0
    Attempt to find the best virtual canvas size that contains the whole
    image.  This however will fail for images with a negative offset as there
    is no way to specify a virtual canvas with negative components. To avoid
    problems it will use the size of the actual image as the smallest canvas
    size possible.  That is it will never assign a virtual canvas with a zero
    dimensions.

  -repage 0x0+X+Y
    Move the images offset then resize the virtual canvas to best fit the
    images new location.

  -repage 0x0+0+0
    Equivalent to a +repage, +set page or -set page 0x0

  -repage WxH+X+Y
    Equivalent to a "-set page WxH+X+Y".  That is just assign the given values
    directly.

Note the use of a '!' flag will make the given offset a relative displacement
to the images current offset.  That is a '-repage +5+0\!" will move the images
offset 5 pixels to the right, without modifying the virtual canvas size.

Caution is required in giving an image a final negative offset position
as the GIF file format can not handle this, and resets it to zero if negative.
Also some browsers go crazy when given PNG images with negative offsets.

What virtual canvas information is saved with an image is format dependent.
   JPEG like most image formats do not save virtual canvas information
       at all.  The information is just ignored.

   GIF will save the size of the virtual canvas and offsets as part of its
       GIF animation handling.  However it will not handle negative offsets.
      Any negative offset will be reset to zero on save.

   PNG will save offsets and even negative offsets but does not normally
       save the virtual canvas information.  However PNG images saved by IM
       will contain a extra profile attribute to preserve virtual canvas size
       info for use by later IM commands.  If IM does read a PNG image without
       this IM specific attribute, it will set the image virtual canvas to
       the best size to show the whole image (as per a -repage 0x0)

Some formats like GIF and PNG save virtual canvas information, others like
JPEG do not.  All of the above formats have there own limitations for virtual
canvas information.  Only the internal MIFF file format does not have any such
limitations.

Note that "-page" has special meaning for "text:" and "ps:" image generator operators (See Text: Multi-line Text Files and Ps: Postcript formated Text and Graphics). As such its normal canvas size and offset meaning are not used during the creation of these images.

Special 'Out-of-band' Settings

-set option:{operator}:{setting}  {string_value}

  For example   -set option:distort:viewport {geometry}

  These 'option:' settings override the normal internal working an
  behaviour of operators, and are also usable by used for %[...] type
  escapes of special temporary working meta-data.

  Users can also create random option settings that can be later
  used by Percent Escapes.  See User defined option escapes
  This is especially important for passing image meta-data from one image
  for later use in another image, as labels, or annotations.


-define {coder}:{setting}={value}

  For example  jpeg:optimize-coding=false

  The -define  settings can override the normal behaviour of specific
  image file format coders.  That is, specific settings for specific coders
  that go beyond the ordinary coder settings such as
     -type -quality  -compress  -interlace  -sampling-factor -density

  For more examples see JPEG Write Settings.

Image Storage Color System (Colorspace)

The primary purpose of "-colorspace" operator is to change the way IM stores an image within memory.

Normally each image has 3 (or 4) channels of image data. The current 'color space' of an image determines what the data of each channel represents. Now normally the channels are named 'Red', 'Green', 'Blue', as that is normally the type of image data that is stored in those channels. However that is not always the case.

Don't think of the 'R' or 'Red' channel as being red, think of it as 'channel 1' whcih could contain data for 'red', 'hue', 'cyan', or other things depending on the colorspace of the the image. 'Red' is just a label for the channel typically used for 'red', or the first channel.

As the second most common colorspace used is CMYK, the same 'RGB' channels also has an alternative naming of 'Cyan', 'Magenta', and 'Yellow', though they refer to the same set of channels as used for RGB images. A special fourth color channel is also added for CMYK, for 'Black' (note that K = blacK).

This basically means that the color channel for "Green" actually refers to the exact same color channel as would be used for "Magenta". Whether the data itself is 'green' or 'magenta' depends NOT on the name of the channel, but the 'colorspace' of the image in memory.

There are two operators that allow you to control an images colorspace...

The "-set colorspace" (Add IM v6.4.3-7) will change just the in-momory images 'colorspace' setting. that is it can convert a RGB image into a HSL image but without changing or modifying the actual pixel data that the image is using. The most typical use of this is when Combining Channel Data to set what is the final colorspace of the combined image. The other more common control is the "-colorspace" operator. This not only sets the images 'colorspace' but will also map the image's pixel data from the old colorspace into the new colorspace, changing the stored data appropriatally.

For example here we separate the color channels of the built-in "rose:" image as RGB, which is what the image is stored as normally in memory.

  convert  rose: -separate rose_RGB_%d.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]

But if we ask IM to re-map the image's pixel data into a CMYK colorspace representation, then we can extract gray-scale copies of channel data in that image representation.

  convert  rose: -colorspace CMYK -separate rose_CMYK_%d.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]

While most operators within IM work correctly for images with CMYK and CMYKA color channels, some do not. This is particularly the case for the "-draw" operator, which does not understand the 'black' channel. This is being fixed as they are found. For example, blur and resize handles these type of images correctly, and as of IM v6.3.3 rotates also handles that colorspace.

Report any CMYK operational failures to the IM Bugs Forum. Typically it is the black channel that breaks during some image processing operation.

Note that a 'Gray' colorspace only faked by ImageMagick and remains represented by three RGB color channels. All three channels will however contain exactly same 'Gray' channel data, instead of just one channel, until the image is modified.

  convert  rose: -colorspace Gray -separate rose_Gray_%d.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]

For more detailed examples of extracting the individual channels from image formats see Separating Color Channels.

Image colorspaces involving a 'Hue' can be extremely difficult to work with, as the 'Hue' channel is circular (using modulus mathematics), that wrapps around from maximum to minimum at a pure 'red' hue.

For example, notice the sharp black and white boundaries that exist for the first 'Hue' channel image for this HSL representation of the built-in rose image.

  convert  rose: -colorspace HSL -separate rose_HSL_%d.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]

ImageMagick itself does not have a good internal understanding of Hue, and especially of color distances involving a hue color representation. This has proven difficult to solve, especially for important tasks such as Color Quantization and Dithering.


On top of the 3 (or 4) color channels, an image also has an optional transparency channel. Internally this is currently represented as a 'Matte' channel with '0' for opaque and 'MaxRGB' for transparent. See the next section Controlling Image Transparency for methods to control this important optional data channel.

Of course converting image colorspaces is actually better done using Color Profiles which define the colors and gamma corrections used in images, when saved. But only a few image file formats understand and use such profiles.

For more information on different color spaces see Wikipedia, RGB color model, CMYK color model, HSV (HSB) color space, HSL color model, YUV color space.

Controlling Image Transparency

The transparency channel of an image is completely optional, and often requires special handling separate to the normal 'color' channels. See Image Color Space above.

The existance of a transparency channel can also effect how the various operators treat the other color channels, generally because a fully-transparent color should often be completely ignored by an operation. This this was not the case you get 'Black Halos' around images, such as was seen in major IM Bugs in the early days of IM v6. For example the Resize Halo Bug, and the Blur with Transparency Bug.

There are two operators that allow you control the transparency channel of an image in memory. The older one is "-matte" while a newer one with a lot more methods is "-alpha method".

The newer "-alpha" methods are now the recommended method of control, though most IM Examples still show and use the older "-matte" version.

Here are the various "-alpha" methods and examples of how they effect images and there transparency.

Off or "+matte"

This is just a simple switch on the image, as turns off any effect the transparency has on the image. For example lets take a PNG image of a 'cresent moon' image (see right), then turn the image alpha channel off.

  convert moon.png  -alpha off     alpha_off.png
[IM Output] ==> [IM Output]

Note that the moon shape completely vanished when the transparency was turned off, though that is actually rarely the case. Basically even the 'transparent' areas have color, which is just not normally visible, in this case the hidden color was the gradient that was used to help create moon in the first place (see Copy Opacity Example where the this image was generated).

This hidden color could be anything, from a simple ' GIF Transparency Color, that the GIF format uses to represent transparency in its color table, to garbage colors left behind during the images creation as above. Most typically the transparency color is a pure black for any pixel that was fully-transparent (a way from the edge of the original object in the image.

Note that while the transparency channel has been 'deactivated' or 'turned off' like a simple switch, the data itself has not been cleared or removed from the image that is in-memory. It is still present, just unavailable at this time.

Be warned that saving the image with the transparency data turned off, will not save any transparency data to the image file format, and that data will be lost.

Also as many file formats do not allow transparency (such as JPEG), these file formats automatically do the equivelent of a "-alpha Off".

The "+matte" operator is an older command that is exactly the same as "-alpha Off". That is it just turns off the transparency channel.

Note that this method is often required when using a gray-scale mask image with the CopyOpacity Alpha composition method.

On

The 'On' alpha method is also just a switch which just simply turns on the transparency data again. As before it is a simple switch that just 'activates' the transparency data channel. Any existing transparency data is not modified, though if the image did not have any previous data, the data itself is initialized as fully-opaque.

For example here we turn 'Off' the transparency data, then turn it back 'On, reproducing the original image.

  convert moon.png  -alpha off  -alpha on    alpha_on.png
[IM Output]

Note that this is NOT the same as the older "-matte" option (see the 'Set' method next), and in fact this option is should not be needed to be used very much, except in special situations.

Set or "-matte"

The 'Set' alpha method is the same as the "-matte" option. This not only ensures that the image has a 'transparency' or alpha/matte channel, but if the alpha channel was NOT currently 'active' it will clear it to be fully-opaque (See 'Opaque' next). This is typically used after reading images which may not have an alpha channel, such as JPEG, my later processing of the image will need one.

So repeating the previous example with this method we will see that the image remains opaque (with the colorful background), even though the alpha channel had previously existed.

  convert moon.png  -alpha off  -alpha set    alpha_set.png
[IM Output]

This is the recomended way of ensuring an image has an alpha channel after reading it into memory.

Opaque

This method not only ensures the alpha channel is 'active' but that it is also completely opaque, regardless of if the image had transparency 'activated/on' or 'deactivated/off'.

As such the last example could have also been achieved using...

  convert moon.png  -alpha opaque    alpha_opaque.png
[IM Output]

The original 'shape' of the image can no longer be recovered after this operation.

Transparent

Similarly this ensures the alpha channel is 'active' but fully transparent.

  convert moon.png  -alpha transparent    alpha_transparent.png
[IM Output]

The color data of the image is still present, so turning off transparency afterward will again show the images existing colors.

  convert moon.png  -alpha transparent  -alpha off  alpha_transparent_off.png
[IM Output]

Also as before the original 'shape' of the image can no longer be recovered after this operation.

Extract

The 'Extract' method will simply copy the 'alpha' mask of the image as a gray-scale channel mask.

  convert moon.png  -alpha extract    alpha_extract.png
[IM Output] ==> [IM Output]

Note that fully-opaque is white, while fully-transparent is pure black. However as the image contained some semi-transparent pixels along the edges (for anti-aliasing, providing the images shape with a smoother look) there will be some gray colors in the above output.

The alpha channel of the image is also turned off or 'deactivated' by this method, but it is not cleared, so turning the alpha back on will re-create a shape mask of the original image.

  convert moon.png  -alpha extract -alpha on   alpha_extract_on.png
[IM Output]

However while the above looks 'white' the edge pixels will be various shades of gray. We can see this if we now flatten the image onto a white background.

  convert alpha_extract_on.png  -background white -flatten alpha_edge.png
[IM Output]

These 'gray' pixels are actually used to good effect in Edge Outlines from Anti-Alised Shapes to generate a smooth edge or outline from a image shape.

This side-effect of saving the alpha channel, has particular benifits when Using the Shade Operator, which does not understand or use the alpha channel of an image. See the sub-section, Masking Shaded Shapes.

Copy

The 'Copy' method is the reverse of 'Extract', and essentially performs a CopyOpacity against itself. That is it will turn a gray-scale image (regardless if its alpha channel is enabled or not) into a shape mask image.

  convert alpha_extract.png  -alpha copy   alpha_copy.png
[IM Output] ==> [IM Output]

It does not matter if the image had an existing alpha channel or not, all it does is create the images transparency from the image grayscale values.

Once you have a shape mask, you can use various Color Tinting or Duff-Porter alpha composition methods, to color it. For examples of using a shape mask see Masks as Colored Shapes.

Shape

To make use of a greyscale image easier, the 'Shape' method not only creates a shape mask, but will also color it using the current background color.

  convert alpha_extract.png -background Yellow -alpha shape   alpha_shape.png
[IM Output] ==> [IM Output]

This means you can very quickly color a greyscale mask simply by shaping the image, then flattening it onto a different background color

  convert alpha_extract.png -background Yellow -alpha shape \
                            -background Blue   -flatten  alpha_color.png
[IM Output]

Of course a faster and better way to map a black and white to specific colors is to use the more specialised Level Adjustment by Color which will do the color gradient replacement without requiring transparency to be enabled.

  convert alpha_extract.png  +level-colors Blue,Yellow   level_color.png
[IM Output]

Palette Channel

Also optionally present is a 'color palette' map of the image may be defined which represents a list of the colors the image has been color limited to. This map could have been read in from the images original file format (such as GIF), or has been color reduced to (via Color Quantization or user defined a using Pre-Defined Color Map). However if the image contains any color not present in this map, that map is then regarded as invalid.

The 'color palette' is however stored in the same channel as 'Black' as used for CYMK images. and because of this IM can not color quantize CYMK images. Such images will be reduced to RGB instead. You can however quantize CMY colorspace images instead, then remap those back to CMYK.


Image Type when Reading and Writing

The "-type" operator/setting defines the style or color space to use when an image is being read in or written out, to ensure the resulting image (in memory, or in the image file) is what you expect it to be. As part of this, it may do some "-colorspace" operations at the time of the file I/O, though only to ensure the image is in a form that was expected.

For example "-type" has a special 'bilevel' setting that can be used convert and save images as a two color monochrome image for some image formats. Similarly 'TrueColor' and 'TrueColorMatte' can be used force a TIFF image to be saved as a full color RGB image even if the image is actually purely gray-scale.

Other settings include 'GrayScale' and 'GrayScaleMatte' which will ensure the written image is gray-scale only (without or with transparency, respectively). Or 'Palette' to force the use of a indexed color map in formats that support this option, such as PNG.

During reading of image file formats a "-type" setting of 'TrueColorMatte' will force a JPEG image being read is has a 'Matte' or 'Alpha' channel added for its in memory storage, even though the JPEG format itself can not handle transparency.

When writing to a PNG file format setting a "-type" of 'Pallette' will force it to use a color indexed "PNG8' internal image format. Simularly using "BiLevel" will force IM to dither color images to black and white for most image file formats.

Unfortunately the exact meaning and capabilities of "-type" depend on the specific image format you are reading or writing. See the various Image File Formats example areas. For specific PNG examples see PNG output formats.

Quality and Depth

These two terms are often talked about in Mailing Lists and in these example pages, so I'd like to explain them a little. Quality is a compile time setting in ImageMagick, and is used to determine the size of the values use to store images in IM memory and during processing. Basically it means the Quality of Processing that a specific IM was compiled for.

The Depth is the size of the values used when an image is either read or saved to/from an Image File Format. It is as such more highly variable. and controlled by the "-depth" setting, or by the original 'depth' of the image that was read in. more on this in a moment.

Remember...
Quality is 'in memory' value size, and is compiled into IM.
Depth is file format value size, and is variable.

Depth - file format bit depth

Now most image formats are of depth 8. That is they use 8 bits (or a value from 0 to 28-1) to hold each color value used in the image. That is a value of 0 to 255 for red, 0 to 255 for green, and 0 to 255 for the blue channel. More usually this type of image is referred to as 24 bit images (total bits, NOT the channel bit depth), and includes such formats as such as JPEG), or 32 bit images if you also have an alpha channel, such as a typical PNG images).

What a lot of people refer to as 8 bit images, are really a image with an 8 bit palette or color map (giving a 256 color limit over the whole image). While such images are also a 8 bit depth, that is not what is being referred to. GIF images are a good example of this.

Transparency in such images are usually handled either by specifying a specific color as representing transparency (set using the "-transparent-color" meta-data setting) as in GIF format, or using a special profile for a specific number of colors in the color table in a PNG8 image. However only a single color transparency is implemented in IM bit image formats at this time.

In general...
24 bit images are : 3 x 8 bit depth values 3 color channels only
32 bit images are : 4 x 8 bit depth values 3 colors + Alpha channel
8 bit images are : 8 bit color mapped image, with 256 color limit

Because of this a lot of people install IM using a 'Q' or Quality level of depth 8, which requires less memory and processes images faster than a more normal Q16 version of IM. These Q8 versions work well, and are good for generating simple images, annotating, or overlaying images. However a low quality while faster and more memory efficient, falls does when you start using complex multiple sequences of operations that could produce serious bit level effects (see below).


Quality - the in memory bit depth

Remember, Quality is a compile time setting in ImageMagick, and is used to determine the size of the values use to store images in IM memory and during processing. It can not be changed, except by re-compiling ImageMagick from sources.

A 'Q16' ImageMagick thus will use twice as much memory as a 'Q8' version of ImageMagick, and depending on your CPU, could be slower, though on today's processors that is not very likely. Similarly you can compile 'Q32' and 'Q64' versions, though these are not very common. Also see the new HDRI compilation quality option below.

A 'Q16' ImageMagick also allows you to save more bit information for each pixel value. That is color values are saved as integers ranging in values from '0' to '2^quality-1'. That last value is known in IM programming as the current 'QuantumRange' (or the older obsolete name 'MaxRGB').

The higher the Quality Setting, used when compiling IM, the more precise the color values used to store the image in memory. That means that if in processing an image you generate a lot of very small, slight variations in color, then those variations will be preserved in the in-memory storage of ImageMagick. In a low quality IM however those effects can expand more quickly producing unwanted color distortions in the resulting image.

Such operations include: noise filters, blurring, sharpening, averaging, or lots of complex image composition operations. In such cases using a Q8 IM for the in-memory bit depth will not work well, and could create very distinct color artifacts on the resulting image.

Of course saving the final image to a 8 bit quality image format will 'quantize' those color values back to 8 bit, but during the processing of the image the quality is preserved, and they will not effect later operators as much.

Some formats are available that preserve the higher quality level information used by IM. For example the MIFF IM format, the enumerated pixel TXT format, as well as the NetPBM image formats. However a Q8 version of IM while it will let you output a 16 bit depth image, will not does not improve the overall quality of the saved image, as that information is not available.

If IM reads an image from a 8 bit quality image format, the images 'depth' will be set to 8 bit, and by default it will save the image at 8 bit depth, even if you process the image using a 16 bit 'quality'. This is true even if you save to a format such as MIFF.

That is the original image 'depth' will be preserved unless you change it using the "-depth" setting, before saving. As such reset that setting if the depth of the saved image is important.

HDRI - floating point quality

IM can be compiled to use a floating point values for images stored in memory, to allow you to perform HDRI styles of image operations. HDRI, or High Dynamic Range Imaging, is designed to more naturally represent our eyes ability to see both bight and dark areas of a scene simultaneously.

The HDRI still uses same color range as the current compile-time Quality Setting for in memory storage. That is values still range from '0' to the 'Quantum Range'. But the values are saved using floating point ('doubles' in C programming terms), so 'quantum' effects from the rounding off of integer values will not be seen. The values are also not 'clipped' when the values go beyond the 'Quantum Range' or into Negatives, though some care may be needed.

That means by compiling IM with HDRI support, (See Enabling HDRI in ImageMagick on the main IM website), you will not loose as much information between processing steps as the results will be saved as a floating point value without quantization or clipping. Using a HDRI quality you can even process images using negative or monstrously huge values. As long and the final color values is in the images normal value range, when it is finally saved (depending on the image file format).

If all the colors of an image is compressed to a very small (or large) range due to processing, the floating point will ensure there is no loss of image quality.

Of course saving a image into a image file format that does not support floating point values will be clipped, quantized, and even color reduced (Color Quantization) to fit the image into that format. As such the image may still need to be normalized before saving it to a normal image file format.

Image formats that can handle floating point values (without clipping) include: the IM internal formats MIFF and MPC, as well as PFM, and TIFF (though only a few applications will understand TIFF with floating point depth quality). However if you want to save the intermediate 'floating point' forms of the images, you may need to give a hint to IM that you want to preserve the floating point values in the saved image by specifying the special option "-define quantum:format=floating-point".

The floating point HDRI will be required to make full use of the new Fast Fourier Transform (FFT) Filtering operators that are currently under development.

FUTURE:  OpenEXR  reference
Examples of HRDI images

Image Density

While in-memory Quality and file format Depth specifies the color 'resolution', the Density of an image is the spatial (space) resolution of the image. That is the density (expressed as dpi, or dots per inch) of an image define how far apart (or how big) the individual pixels, and thus the overall size of the image in real world terms.

The density of an image is completely irrelevant to the actual images pixel size. It is just a set of numbers stored with the image to tell output devices such as printers and displays how many dots (or pixels) per inch the image should be displayed at, OR for vector formats like postscript, pdf, MWF, the pixel scale to draw the image at.

You can set the resolution or density of an image as it is being read into IM by using the "-density" function, before reading the image, or using "-set density" after reading the image in (it is better to do it before reading).

A 200x200 pixel image at 600 dpi will thus be displayed in 1/3 inch square in real world terms. On the other hand a much smaller 72x72 pixel image at 72 dpi will display in a 1 inch square, in the real world, though its spatial quality will not be very good in comparison. That is just how it works.

A "-units" setting can be used to define if the density number is expressed in the default (traditional printing) terms of 'PixelsPerInch' or in more modern metric units of 'PixelsPerCentimeter'.

Remember density or resolution is purely a number stored within an image and has no bearing on the actual image pixel size, or the amount of actual image data that is used to represent the image, it really only the output display size and pixel quality, when the image is actually used on a real world device.

Note that the "Photoshop" image editor saves an extra copy of the images resolution into a separate profile (named '8BIM') in the image, which IM will NOT touch. Thus if you change the resolution of an image with IM, you probably should also strip the profiles from the image before loading it back into "photoshop", or you may not see any density changes. .

For more information see the notes on the Resample Resize Operator.


ImageMagick Operational Controls

IM also has a few special options that it uses to control its operational working, information reporting, and for debugging purposes.
-version Output what version of IM, the image quality it is using, and when was it built.

IM will implicitly exit after outputting this information.

 
-list This is an informational option only and will list the requested items, then exit. That is you can not use this with any other option, or image processing. It is purely provides for informational purposes, especially in scripts to check input options and if IM has certain options implemented.

The given argument defines what information you are wanting to list. For example a list of 'color' names that you can use, (such as using by ("-fill", "-background", "-mattecolor", "-bordercolor"). While 'font' lists the fonts that are specifically known to IM.

Here are just some of the more interesting lists...
font Known fonts (IM also knows about X and PS fonts)
type file image types ("-type" )(after IM v6.3.5-7)
or the font list (before that IM version)
color known color names for various color options.
dispose all the GIF disposal settings ("-dispose")
compose alpha compositions are available (includes internal methods)
layers what multi-image "-layers" methods has been implemented
command what command line options (both settings and operators) are available
list what lists can "-list" list!
configure what were the configuration parameters used to build ImageMagick

That last 'list' setting 'Configure' is very important, as it will tell you what libraries, and delegates were available when IM was built. It also includes the 'point' release number that is usually missing from the normal "-version" output. (See Script Version Handling for one example of using this information.

IM will implicitly exit after outputting this information.

 
-verbose Report extra info on some of the more complex operations.
For example "-segment", which outputs a lot of color quantization details.

This is especially useful to generate for more detailed image information from the "info:" and "-identify" outputs.

 
-quiet Don't report informational warning messages. Only proper errors such as I/O errors, or bad options, etc.

This is especially useful for "-crop" or "-trim" and "-layers optimize" to not report 'missed images' warnings.

This will also quieten some complex image file formats that can contain 'unknown chunks' which IM would normally ignore. For example when IM is reading MPEG (AVI) video formats.

 
-regard
  -warnings
   
Where the previous control option will quieten some informational warning messages, '-regard-warnings', will make them fatal. It also causes IM to return a proper exit status according to such error conditions.

It can be used in scripts to 'sanitize' image file being provided from uncontrolled sources. That is this option will make IM fail and exit, if when the JPEG or TIFF image was not correct, complete or contained 'unknown' profiles.

 
-respect
  -parenthesis
   
Causes parenthesis to not only to save and restore the current image list but also all the current operational settings are saved and restored. Than means that when given, any settings set within parenthesis, will be reset when the parenthesis ends. See the examples in Parenthesis and Settings above.

 
-ping For the "identify" command. Im will try to avoid completely reading and decoding the full image file format for basic information such as the images size.

 
-monitor Report a percentage of processing during each stage of image processing, especially for very large or long image processing tasks.

In a lower level API, you would use SetImageInfoProgressMonitor() or SetImageProgressMonitor()

 
-debug Report verbosely exactly what IM is doing, in various areas.

The argument is a comma separated list of options, such as...
exception What is IM not understanding about the command
cache See how much disk space IM is caching
configure Show IM search attempts to find its configuration files.
all Show every trace point during processing
This is very very VERY verbose and not recommended
annotate Report on font metrics when a font is used with "-annotate".

For command line and API usage you can also define an environment variable to set the debug level using actions by IM.

  export MAGICK_DEBUG=all


FUTURE Section on debugging...

All three of these do exactly the same thing.
   -format '...'  -write info:
   -format '...'  -identify
   -print '...'
Format and output information requested as % escape strings, about the images
in memory, at this point in the current image operation sequence.

Checking on what images are present at each point...

   -write x:   - show the current images
                 waits for you to quit the view before continuing
   -write show:  - show the images at this point, but don't wait!

Add a new delegate, so users can....
   -write montage:   - show images as a montage at this point, don't wait.

Other debugging techniques....

-monitor   watch IM processing the images (with percentages)
-verbose   watch images read in/out and extra output from complex operators
           like -distort, -sparse-color, -segment

-debug   watch the internal calls within the MagickCore Library.
         this is VERY verbose and rarely nessary.

   if -debig is used the location of the logging output is controled by
   the  "log.xml" file.  This is by default set to "Console". to have it save
   to a fiel change  <log output="console"/>  to
   <log output="file"/>


Created: 30 January 2004
Updated: 10 September 2008
Author: Anthony Thyssen, <A.Thyssen@griffith.edu.au>
Examples Generated with: [version image]
URL: http://www.imagemagick.org/Usage/basics/

a