- 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]](append_rotate_bad.gif)
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]](append_rotate.gif)
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
| |
|
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
| |
|
Will produce the same result as this IM version 6 command...
convert storm.gif -flip cmd_flip_postfix.gif
| |
|
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
|
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
|
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).
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
Or delete everything (and add a new image)...
convert font_[0-7].gif -delete 0--1 tree.gif seq_delete3.gif
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
-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
| |
|
-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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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
| |
|
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...
- modify image attributes or meta-data as they are read in.
- output control settings, including some format library controls,
- global settings used by many different image processing operators.
- and also a few special operational settings.
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
|
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
| |
|
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
| |
|
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
|
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
|
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
|
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 2
8-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