ImageMagick v6 Examples --
Basic Usage

Index
ImageMagick Examples Preface and Index
ImageMagick Command Line Processing
ImageMagick Commands
Image Sequences
  • Combining Image Sequence Operations
    Image Attributes and Settings Under Construction
    ImageMagick Operational Controls Under Construction
  • 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 append the images together first, then the result of the append will be rotates, 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 catogory.

    Input Settings are specifically restricted to controling 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 speical 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:

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

    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 have been defined.

    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, (involving two, three, or many images), animation handling, color channel handling, etc...
    +append  -mosaic  -flatten  -fx  -composite  -combine  -separate  -coalesce  -deconstruct  -layers

    Image List or Sequence Operators are new to IM v6 and effect the ordering of images currently in memory.
    (  )  -swap  -delete  -clone  -insert  -reverse

    See Image Sequences below for more details.

    Special Operators are operators that do things in unusual and non-standard ways.
    -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 explicitally 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.

    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 +append output.gif
    
    [IM Output]

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

    convert 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
    +append Join all 3 images in sequence horizontally (fill with white) 1 (merged)
    output.gif As this is last argument, this is the output image filename.
    Output the single image in the image sequence.
    seq 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 and see what the result would be. Each previous release of IM would also probably have produced a different result as well!

    Version 6 should be 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 in an image to apply the operator to.

    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 commandline 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). As such there is no guarantee of the order of multiple operators will be the same as the order you give.

    Also as commands 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, but that 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 Orientation images, 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 somethng 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 the various distortion Animation shell script generators.

    API's however have no problem with looping over the images, or even dealing with a whole array or data structure of image lists (wands).

    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

      By default it outputs a quite summery about the image in question.
      ... details ...
    
      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.
    
      Specific information can be obtained by using -format. and even some
      mathematics can be returned.
    
      As of IM v6.2.4 you can also use this as an equivalent form of identify.
            convert image info:
    
      You can also output image information  in the middle of image processing.
       or   convert image -write info:-  ...more options... result_image
       or   convert image -identify  ...more options... result_image
      However as the above outputs to STDOUT, you can not pipeline an image into
      another image processing command.
    
      However you can save output to a file to free STDOUT for pipelining
      For example to output the number of colors in an image at a particular point
      in image processing.
    
         convert image ... -format %k -write info:info.txt ... miff:- | ...
    
      * 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:").
    
      * 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.
    
      * You can bypass this full read for some image formats by using a special
        "-ping" option.
        (See Ping, Operational Control below).
    
      * 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:" or "win: 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 showen correctly. Better to use "display" when transparency is involved.

    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

    If a single mouse click is used the whole window clicked in is grabbed and returned. Note that it will try to raise the window to the top so that no other windows are obscuring the selected window being grabbed.

    A click in the root window will return the whole screen.

    If you click and drag the mouse, a smaller section of the visible screen is returned.

    Other options allow you to avoid human interaction with the mouse by grabbing the whole screen ("-window root"), or a specific window (given 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.

    Note that in the last example that I needed to put a backslash '\' before the bracket. 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.

    Also please note that 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.

    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.

    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:Candice \( label:'inside'  \
              -font Gecko   label:Gecko   \) 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.

    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 silentally 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 effectivally 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), effectivally 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]

    -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 seperated 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'), then "-separate" out all four color channels of that one image, "-swap" the red and blue channels, and re"-combine" them, back together. I then "-delete" the original image, and "-insert" the color modified one.

    
      convert font_[0-3].gif \
              \( -clone 1  -channel RGBA -separate -swap 0,2  -combine \) \
              -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 has now been modified. 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  -channel RGBA -separate -swap 0,2  -combine \) \
              -swap 2,-1  +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. Alternativally 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 -coalease 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 simular 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 settings not normally used.
              -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 relevent to
            I/O operations of images, such as JPEG, PNG and TIFF.
    
            For example...
              -define jpeg:preserve-settings
              -define -define jpeg:optimize-coding=false
            See Writing JPEG Images
    
            The equal sign is required, when the define requires
    
            This are global defintions 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 controled 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 tha 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 traditionnaly 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 undefine 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 -1,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.

    Alturnative 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.

    The Page Attribute

    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 area, or 'canvas'.

    For a individual image this is not so important, but when you have two or more images you need to remember how images are positioned relative to each other. For example in an animation, or when overlaying distorted images on top of each other to form a larger panarama.

    It is also used, (and hence its name of '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.

    It is especialy important in organising Layers of Multiple Images and in GIF Animations. However it is also involved with remembering the original positions of images when Cropping Images, 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

    Controling 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 vitural canvas
    attribute to an existing image.  However a thrid 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 image file format, as many browsers use the
        canvas/offset information as part of there display.
    
      -repage WxH
        change the 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 without changing that canvas
        size
    
      -repage +X+Y\!
        Do a relative move of the image on the virtual canvas
    
      -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 posible.  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
        Equivelent to a +repage, +set page or -set page 0x0
    
      -repage WxH+X+Y
        Equivelent 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 virutal canvas size.
    
    Caution is required in giving an image a final negative offset position
    as GIF can not handle this, and some browsers go crazy for PNG images
    with negative offsets.
    
    What virtual canvas informaion is saved with an image is format dependant.
       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-ofband' 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 usally (but not always) the data is representing a RGB image. These names still represent those same channels no matter what 'color space' the image is really using.

    As the second most common colorspace is CMYK, the same channels also has an alturnative 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, of '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 on how the image is currently stored in memory, and that is controled and converted by the "-colorspace" operator.

    For example here we separate the color channels of the built-in "rose:" image as RGB, whcih 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-organise the image into say a CMYK representation, then we can extract gray-scale copies of that image representation.
    
      convert  rose: -colorspace CMYK -separate rose_CMYK_%d.gif
    
    [IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]

    Note that the single channel 'Gray', color space still uses all three RGB color channels. Basically all three channels will contain the same converted channel data, instead of just one channel, as you would expect.
    
      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 Color Channels.

    Unfortunately few IM operators understand the color associations involved with image representations, other than 'RGB' or 'CMYK' color representations. Those color spaces involving a 'Hue' channel for example, generally do not comprehend that the data representation is circular which wraps around on the hue red.

    While most operators within IM work correctly for images with CMYK and CMYKA color channels, some do not. 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.


    On top of the 3 (or 4) channels, an image also has an optional Matte (or inverted Alpha channel. The existence of this channel is controlled by the "-matte" operator.

    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 invalid.

    Of course converting image colorspaces is actually better done using Color Profiles which define the colors and gamma corrections used in images, when saved.

    Other than for the RGB like colorspaces and CMYK, few operators comprehend any inherent attributes of color spaces. For example the cyclic nature of Hue in HSB and HSL colorspaces is not currently understood by the IM Color Quantization (reduction) subroutines.

    Only various channel restricted gray-scale operators, like "-negate", "-threshold", and "-ordered-dither", can truly handle images in other colorspaces. Basically only operators that treat the channel data as being completely separate to each other.

    Caution is advised, or you may have unexpected results.

    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.

    Controling Image Transparency

    Old operator...
       +matte    turns off
       -matte    turns on (and if Off, sets it to fully-opaque)
    
    The new operator   -alpha   is designed specifically give users a finer
    control the alpha channel (still under test).
    
       On, Off
              is matte channel valid or not, the original content is unchanged
              (working)
    
       Activate,  Deactivate
              are colors to be transparency effected.
              That is does a fully-transparent colour effect the results.
              If deactivated a the alpha channel is just a channel without
              effecting color channels,  this can produce 'black-halo' effects.
              (Yet to be implimented)
    
       Set, Reset
              make alpha channel fully-opaque, or fully-transparenct resp.
    
              However I have proposed this method names be changed to..
                 Opaque and Transparent
              to make it clear what they do, as currently it is unclear.
    
    Future
       Copy     convert a gray-scale image to become its own alpha
                That is, make a "gray-scale mask" its own "shape mask"
    
       Extract  The reverse of the above, a seperate alpha channel varient.
                EG: -fill white -background black -colorise 100% -layers merge
                OR: -channel A -seperate +channel
    
    
    The Activate/Deactivate settings are in development, and the reason for this
    options creation.  It will be used to control whether alpha channel effects
    the colors used in the other color channels. That is transparent is really
    transparent and controls the color contribution of semi-transparent colors.
    This is especially important in operations such as: resizing, blurring,
    convolution, distortions, etc, etc.
    
    Remember...
    The GIF format uses one special color table index to specify what in the image
    is to be regarded transparent.  Of course this color table index also has a
    color, to which programs that do not understand transparency, can fall back to.
       -transparency-color
    
    

    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 monochrome in some image formats. Similarly 'TrueColor' and 'TrueColorMatte' can be used force a TIFF file save to be RGB even for gray-scale images.

    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 limited 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.

    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 a specific example 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