- Index
- ImageMagick Examples Preface and Index
- ImageMagick Command Line Processing
- ImageMagick Commands
- Image Sequences
- Image Attributes and Settings
- Setting/Changing Image Meta data
- Page, Repage and Image Offset Control
- Special 'Out-of-band' Settings
- Image Storage Color System (Colorspace)
- Controlling Image Transparency
-
Off,
On or -matte,
Set or +matte,
Opaque,
Transparent,
Extract,
Copy,
Shape
- Pallete Channel
- Image Type when Reading and Writing
- Quality and Depth
-
Depth,
Quality,
HDRI
- Image Density or Resolution
- ImageMagick Operational Controls
Here we explain in detail the command line processing that IM follows, some of
the new image processing abilities, the ideas, philosophy, and methodology,
and what is actually going on, internally.
With this background knowledge the rest of the examples provided pages becomes
much clearer. Even if you only use the Application Program Interface (API),
this section is well worth knowing and understanding.
ImageMagick Command Line Processing
Why did the command line style change! or...
The problem with previous versions of IM
In previous major version of ImageMagick (version 5.5.7 and earlier) the
command line interface into the IM library has been prone to problems
involving the order in which operations were performed. It was very
haphazard, and confusing to anyone trying to make sense of what was actually
going on. Also, what worked one time may not work in the same order another
time, as the author of IM, constantly battled with the interface to get it
to work as people expected.
The cause of the problem was that ImageMagick followed a fairly standard UNIX
command line style...
command [options] input_image output_image
As time went on this started to produce problems, as images are complex
objects with an enormous number of operations that can be performed on them
often involving other images.
As a consequence of this the above slowly expanded to become..
command [options] image1 [options] image2 [options] output_image
This worked, and is the basic style that was used in version 5.5.7.
The various image operations such as "
-negate
", "
-resize
", and "
-crop
", etc, could appear either
before or after the image it was meant to apply to.
For example under version 5.5.7 the following two commands were equally valid
and did the same thing.
convert -negate image.gif output.gif
convert image.gif -negate output.gif
|
The problem was what if you were dealing with two images! For example...
convert -size 40x20 xc:red xc:blue \
-append -rotate 90 append_rotate.gif
|
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.
With ImageMagick version 6 however, the operators will always be applied in
the command line order as given by the user. That is, the two images will be
appended together
first, then the result of the append will be
rotated, producing this...
If the user actually intended to do the rotations before the append, he can
explicitly ask IM v6 to do it in that order.
convert -size 40x20 xc:red xc:blue \
-rotate 90 -append append_rotate_bad.gif
|
This sort of fine control was just beyond previous versions of IM, and would
probably have required a pipeline, or intermediate save images to achieve it.
The solution to the problem, unfortunately required a drastic measure and some
incompatibility. On the other hand just about every 'simple' command that
worked in IM version 5 will works as you would expect IM version 6.
In essence command line usage in versions before version 6 was ill-defined and
in my thinking broken, producing numerous odd and unexpected results.
Types of Options - Operators and Settings...
A summary of the following is now also available from the
ImageMagick Website on
The
Anatomy of the Command Line.
All command line options will now fall into two basic groups: 'settings' and
'image operators'. Settings set values, Operators actually preform some
action.
Setting Options
|
|
are command line options that only save information, that will be used
later by other 'image operators'. That is they do not do anything, except
set some value, to be used later.
Many of the options have both a '- ' and a '+ '
style. The latter is generally used to turn off the setting, or reset it
to its normal default state. This allow you remove the effect of a
setting quickly and simply.
For example "+gravity " will return the gravity setting to the initial
'gravity none' state.
Settings can be further divided into a number of sub-categories...
Operation Settings which control how later operators function.
They set the colors, and fonts that may be used by an operator, control
placement of images and text, the lookup of color from source images,
control the method of processing by some of the more complex operators,
etc., etc., etc..
-dither -gravity -fill -background
-bordercolor -stroke -font -pointsize
-strokewidth -box -affine -virtual-pixel
-interpolate
Most setting options belong to this category.
Input Settings are specifically restricted to controlling the
creation of images that are created or read in. Typically they are used
to assign or override specific meta-data that is to be associated with the
image(s) created after that setting was defined.
they are created or read in from an external file.
-label -delay -dispose -page -comment
-size
Remember, they are ONLY applied when an image is created or read in and
are otherwise completely ignored.
Many settings define a string to be assigned which could include special
escape characters, such as '%w ' which will be replaced by the
images width. These escapes are only filled in after the image has been
read into memory, when the setting is actually assigned to the specific
images meta-data.
A special operator, "+set " has been provided to change the meta-data assigned after
an image has been read into memory or processed.
Output Settings which are only used during the writing or saving of
images back to disk.
While they can be given anywhere on the command line, they are only
applied when the image is written, either as the default last image
filename argument operation, or via a "-write ", or "-identify " operation.
-quality -loop -compression -format
-path -transparent-color
If not set, or turned off (using their plus '+' form), an
appropriate default will be used. Generally this default is a saved value
from the last image read in.
A few 'operation settings' such as the current "-background " color, is
also assigned to the image, if the file format requires.
Control & Debugging Settings which control how IM, in general,
performs its tasks. These includes...
-verbose -debug -warnings -quiet
-monitor -regard-warnings
See IM Operation Controls below, for more
information on these special settings.
| Image Operators
| |
Are command line arguments that will modify the image(s) in some way.
They are performed immediately when seen, and may use other
'setting options' that have been given previously on the command line.
These operators can be grouped into a few sub-categories...
Image Creation Operators which will read images from a file or
pipeline, or generate new images. These include...
image.png miff:- xc:color logo:
rose: plasma: gradient: tile:
As 'operators' they are also performed immediately when seen on the
command line. They only add new images to those already in memory, but do
not touch those previously read.
Of course being operators, any previously defined 'settings' may effect
them, especially the "-size " setting, which defines, or hints at the size of the
image you want to create or read in, and other 'input settings', that may
also have been defined, such as "-delay ", and "-page "
Image Modification Operators will modify all images that have
already been read into memory. Each image however is modified separately
to every other image. They include operations such as...
-negate -rotate -crop -flip -flop
-wave -resize -repage -set -shadow
-scale -sample -swirl -draw +matte
And lots lots more...
Because all image operators are performed immediately when seen on the
command line, they must be given after the images for which they
are to operate have been read into memory.
If more than one image is present, all images are operated on, one
at a time. As such you will have to be careful about what image(s) you
have in the current image sequence.
Multi-Image Layer Operators are special in that they modify the
whole current list of images as a single entity. They could replace the
whole list with a single combined image, or modify each image depending on
the other images either before or after it. They are used for alpha
composition, animation handling, color channel handling, etc...
+append -mosaic -flatten -fx
-composite -combine -separate
-coalesce -deconstruct -layers -clut
Remember the whole list is treated as a single entity, and images may be
added, removed, or replaced. Most of the above operators usually merges
multiple images into a single image.
The "-layers "
operator method 'composite ' is currently the only operator that may spilt the
current image sequence into two separate sequences for merger, based on a
special 'null: ' image marker.
Image List or Sequence Operators effect the ordering of images
currently in memory.
( ) -swap -delete -clone
-insert -reverse
The images themselves are not modified, only re-ordered, duplicated, or
deleted. See Image Sequences below for more
details.
Note that parenthesis '( ' and ') ' may require
backslashing or quoting, to prevent any special meaning given to it by
the Command Line shell Interface (CLI).
Special Operators are operators that do things in unusual and
non-standard ways (compared to the above).
-geometry -version -list
The "-geometry "
operator is special as it is the only operator that only effects one image
(the last) in the image sequence, rather than effecting all of the images
in some way. It is only provided for backward compatibility and special
alpha composition requirements. See Geometry, resize just the last image for more details.
The other two "-version " and "-list " are information generating operators, and causes IM to
explicitly quit, after returning the requested information. See IM Operational Controls below, for more information
on these options.
| |
I hope the separation of options into settings and operators is clear as it
is vital to the way IM now works.
Remember under version 6 of ImageMagick...
Settings are saved for later use,
while Operators are applied immediately.
This is what makes version 6 different from every previous version of IM. All
options are defined to be a 'setting' or an 'operator' and the order will
determine exactly when, and to what images, the option will be applied to.
The
IM Examples Options Reference can be used
to identify what is an 'setting' and what is an 'operator'.
Working Example of an IM Command
Let's take a look at an example, and how it will be processed by IM version 6.
convert eye.gif news.gif -append storm.gif tree.gif \
-background skyblue +append output.gif
| |
|
Let's break this down and look at what IM v6 does...
Argument
|
| Action Performed
|
| Images in Seq
|
|
convert
| Initialize and Create an empty 'image sequence'
| empty seq
|
eye.gif
| Read in image and add to end of current sequence
| 1 image
|
news.gif
| Add a second image into sequence (now with two images)
| 2 images
|
-append
| Take all images in current sequence, and append vertically.
All images are replaced by a single image.
| 1 (merged)
|
storm.gif
| Add another image to the image sequence
| 2
|
tree.gif
| And another
| 3
|
-background skyblue
| Set a 'background color' to be used later.
No changes are made to any images.
| 3
|
+append
| Join all 3 images in sequence horizontally
Current background color is used to fill the empty space
| 1 (merged)
|
output.gif
| As this is last argument, and as such is an explict
-write operation. The single image in the current
image sequence is written using the given filename.
| written
|
As you can see the processing of the command line in IM v6 is very straight
forward, and logical, making the result predictable. And that is the point...
In previous versions, IM results were often not predictable and undefined when
multiple operations were performed. You would have basically needed to try it
to see what the result would be. Each previous release of IM would also
probably have produced a different result as well!
Version 6 should see the end of that mess and everyone is urged to convert
to it and re-program your image processing scripts to use it. As things are
settled into this style of command line handling, you should see no further
changes in your results except for bug fixes and operation improvements, as
IM is expanded.
Legacy Command Line Style
Due to the fact that a lot of IM scripts out there use a command with a single
image operator of the form...
command -operator input_image output_image
That is you specified an image operator before you actually read the image
to which the operator will be applied.
To handle this legacy situation, IM will save up all the image operators it
sees, and apply them to the first image when it is finally seen on the command
line. That is the above will work as if you wrote the wrote...
command input_image -operator output_image
For example, this legacy command....
convert -flip storm.gif cmd_flip_legacy.gif
| |
|
Will produce the same result as this IM version 6 command...
convert storm.gif -flip cmd_flip_postfix.gif
| |
|
The legacy command line style works, but has the same problems as IM version
5. All settings are applied before the first read, and all the operators are
just saved away to be executed when the first image is read (and only on the
first image). There is also no guarantee of the order of multiple operators
will be the same as the order you give.
Also as operators are being save up until the first image is actually read,
you may find repeating a command multiple times before reading the image may
result in some of the earlier commands 'disappearing'. This is not a bug, but
a miss-use of the legacy abilities of IM.
This style of command line is for legacy support only, and as such is
depreciated, so should be avoided if at all possible. Any scripts containing
this old style, should also be updated to do image reads before the operators
you want to apply to them.
Command Line vs API
There is a couple of major differences between a command line IM, and using
the Magick API's, such as PerlMagic, and MagickWand.
- Only one Image List or Sequence
- The command line only ever has one Image List or Sequence which can be
worked on at any one moment. You can 'push' or save an image sequence,
temporarily, and even 'clone' images from that 'backup', but you can't
really work on two such sequences at the same time.
Other language API's on the other hand allow you to have as many separate
image lists or 'wands' as you like, and you can work on any of them at any
time, or transfer images between the various lists.
That means you can not easily do things such as merge or combine two
separate image lists from the command line, though some methods have been
worked out for special operations such as Multi-Layer Alpha Composition of Image
Lists.
- Direct Access to Pixel Data
- Again you can so some math processing and merging of pixel data from the
command line, but you can't easily look up attributes, or read and modify
a specific pixel or area using the command line interface.
You can however merge and mathematically modify pixel data of images using
the special FX Image Operator, but it is
limited to transforming whole images, is interpreted, and very very slow.
API's can do this in a much more direct manner. Though some still feel the
provided functions are limiting, however this API allows IM to use
threaded programming, and to allow cloned images to share the same
(unmodified) pixel data store.
- Conditional Processing
- While the IM command line interface can not modify images based on some
image derived attribute. For example you can not process images
differently depending on if the image uses a light background, or a dark
background.
Yes you can do some limited and specific conditional actions using the FX Image Operator, or ask IM to adjust
(rotate) an image's Orientation
based on certain conditions, or only shrink and never enlarge when Resizing Images. But these are only handling
special well known and common processing conditions.
The only truly practical way do conditional processing is to use
separate commands and temporary files. For an example see the well
commented Jigsaw Script.
API's on the other hand can do this type of conditional processing all in
memory, as and when you need it.
- Looped Processing
- You also can not loop over each image, and do something different to each
image based on the image 'scene' number. For example draw text at
different sizes, or gradually blur an image. For any number of images.
Yes you can modify specific images in a image list. For example see Frame by Frame Modification of an
Animation. But you must know how many images are in the image list,
and 'un-roll' the loop to process each image in the list separately.
The only truly practical way to loop over images from the command line is
to write out the individual images as separate image files (see Writing a Multi-Image Sequence and process
them one at a time in an external scripted loop, for example see Appending Animations. Alternatively,
generate the command with the un-rolled loop using a shell script, for
example see shell script Programmed
Positioning of Layered Images, or the various Distortion Animation shell script
generators.
API's however have no problem with looping over multiple images, either in
a single image sequence, or even multiple separate image sequences, or
even with a whole array or data structure of image sequences.
If your application needs to be able to do any of these things (though few
common applications need to do so) then an API may be better, than the command
line.
The "
conjure
" program (see below) was
originally designed to allow better scripted use of ImageMagick, allowing the
use of multiple image lists. The improvements made to IM v6
"
convert
" has seen this experimental API fall into disuse.
ImageMagick Commands
While the bulk of these ImageMagick example pages use the
"
convert
" command to process images, their are a number of other
ImageMagick commands, which I'll briefly introduce here.
Some of these commands however can not be demonstrated properly on a web page.
However I will try to give you hints and tips involving those command here,
even if I can't actually show their output directly, here.
Convert -- Convert between Image formats
But also process and transform the images!
The "
convert
" command is the main workhorse of ImageMagick, and
as such just about every set of examples in these pages uses this command.
As such I will not cover the use of this command much here, but lets look at a
little history instead.
The command original commands purpose when IM was first created was for the
conversion of images in one image format into another. In fact it is still
used for this purpose.
Because of this the command may not even read an image into memory, but may
use secondary
Delegate programs outside IM
proper to do the conversion directly. This completely external aspect however
has fallen into disuse over time, and lack of need, except as a means of
reading in and writing out complex images file formats.
Over a long period of time some extra image processing features was added to
make minor changes to images as they were transferred between formats, or even
the same format. These were generally simple options, but as of IM version 5
the use of these processing features had become extensive, and more important
than just image conversion.
As option multiplied and multiple options were used, the order of the options
started producing weird and uncontrollable results. To users IM became known
as unstable and uncontrollable when multiple image processing options was
used, and it started to fall into disfavor.
IM version 6 saw the switch from a simple 'options' style, to a 'do it as you
see it' style for image processing, and as a result, image processing
abilities become stable, predictable and IM's ability became many orders of
magnitude more complex.
As a result of this, "
convert
", is no longer so much about
'converting' images from one format to another, but as a command line API for
accessing image processing functions, to create, and modify images in very
complex ways, without needing a degree in image processing, or programming in
some other computer language (such as Perl, PHP, or C).
Mogrify -- in-place batch processing
The "
mogrify
" command is in many ways like "
convert
"
except it is designed to
modify images in place. That is it's primary
purpose is to read images (or animations), one file at a time, and modify
them, before save the image back into the exact same filename the image was
read from. Because of this...
Mogrify is dangerous, and can destroy the original image!
As such, before you do anything final, test "
mogrify
" with a
separate copy of your images. Do not do use it on an original image.
Now while "
mogrify
" normally saves a modified image into the same
filename, it has one special 'mode' in which is saves it to a different
filename. The "
mogrify
" specific setting "
-format
", defines a different
format and suffix to use when saving files.
As such a command like...
mogrify -format jpg *.png
|
Will allow you to convert, or batch modify images, without destroying the
original image. In this case converting all PNG files into JPEG files with
that same filename but a different suffix. However be warned that if existing
file with the same name will be
over-written.
So let me re-iterate...
Think and check before you Mogrify
or you may find you just overwrote something you wanted to keep.
As of IM v6.2.0 you can also use a new "
-path
" option to specify a
different directory in which to output the processed images. This make it
safer, however it will still overwrite any images of the same name that may
already be in that directory.
As such you can create a thumbnail sub-directory using something like this...
mkdir thumbnails
mogrify -path thumbnails -thumbnail 100x100 *
|
|
Before IM v6.3.4-3 the "-format " and "-path " settings were mutually exclusive. Upgrade if you need
to use a different directory as well as a different image format for your
output.
|
Due to the multi-image processing capability the "
mogrify
"
command is a little more complicated, than that of "
convert
" as
there are no specific input images, only a list of image images, which
determine the output image filename to be used.
As some setting options are needed to be set before the first image is read in
(for example (for example "
-size
", "
-label
" and "
-density
"), these options are processed and set before the first
image is read in. After this each image is read in and the operators applied
to them in command line order before the image is saved and the next image
read in.
It is important to keep this in mind as if you change one of these settings
later in the sequence you can make IM forget a previous setting.
For example..
mogrify -format gif -size 200x200 -pointsize 18 \
-font Candice -gravity north -annotate 0 "%f" \
-font Ravie -gravity Center -annotate 0 "%f" \
-font Gecko -gravity south -annotate 0 "%f" \
-size 100x64 xc:gold xc:orange xc:tomato
|
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
The "identify" command is designed to return information about an images in a
simple and useful way. By default it outputs a simple compact summery,
detailing the images name, file format, image size, virtual canvas size and
offset, color depth, internal format type, and if known the original size of
the image on disk in human terms.
For example...
Not that the '
8c
' in the above result is not the number of colors
within this image (which is actually 6 not 8), but the 'pseudocolor' palette
size (see later example for actual number of colors). Also note that the image
'virtual canvas' is the same size as the actual image with a zero offset,
meaning it is currently not being used.
Adding a
-verbose
,
Operational Control, will produce as much information about the image
that IM knows about or can easily calculate. This includes color statistics,
color counts, profile information, internal image save type of the image, etc.
etc..
You ask IM it only read basic information about an image using a special
"
-ping
" option. This
causes identify to attempt to only read enough of the image file to determine
simple image information, such as size, without trying to read the whole image
into memory. Most image file format will allow you to do this, but not all.
This is the biggest advantage of "
identify
" over the many "
convert
" image information output operators. (See
Ping, Operational Control below). For example.
Specific information can be obtained and output in specific ways by using the
"
-format
" setting, and
IM special percent ('
%
') escapes to output
Image Properties.
For example you can just extract a count of the number of colors within an
image.
identify -format '%k' tree.gif
|
You you can format the image information in a form that is directly usable in
a web pages. You don't even need to limit it to just a single image either!
Note the output difference between a '
%i
' and a '
%f
'
in the results generated.
echo '<HTML><BODY><CENTER>'
echo '<H1> Some Image Thumbnails </H1>'
echo ''
identify -ping -format '<IMG SRC="%i" ALT="%f" WIDTH=%w HEIGHT=%h>\n' \
../photo_store/anthony_* ../photo_store/*_tn.gif \
tree.gif storm.gif ../images/logo.gif
echo '</CENTER></BODY></HTML>'
|
You can see the result of the above output as a
HTML Web Page showing the images. Of course if you want to do other
things like link the tags to a larger image, you may need a more complex
thumbnail handling script (See discussion about
HTML Thumbnail Pages).
Even some floating point mathematics using
FX Expressions is perfectly valid.
identify -ping -format 'double_width=%[fx:w*2] PI=%[fx:atan(1)*4]' tree.gif
|
Note that the math does not even need to be related to the image itself,
allowing you to use IM as a simple floating point calculator for us within
your scripts.
As of IM v6.2.4 you can also produce identify output from the "
convert
" command, either as the final output
result, or even in the middle of a longer image processing sequence. See the
special "
info:
" output file format
for details.
Some extra notes about identify (still to be formated)...
* Normally IM reads in the image into its own data format, using various
image library APIs and delegate programs, before outputting the results it
sees using identify. That is "identify" analyzes the full image/data
content, not the specific file format the image is using for storage.
This is important as there can be very specific aspects of specific
file formats that "identify" will not report on. For example while
it lists the contents of a GIF image color table for each image
present (multiple images are possible), it will not tell you if all
the images in the file share the same color table or not.
If you need specific info about specific image file format, it may
be better to use a tool designed specifically for that format. For
example "giftrans" for the GIF file format, and "jpegtrans" for
the JPEG file format.
* Note that if image has more that 1024 color no histogram or color tables
will be included in the verbose output. To force the generation of this
info use 'histogram:' to generate it as a image comment. See histogram:
").
* The identify program returns a non-zero exit status if a corrupted image
is encountered and you add a
-regard-warnings
, Operational
Control.
error=`identify -regard-warnings image 2>&1 >/dev/null;`
if [ $? -eq 0 ]; then
echo "The image is good"
else
echo "The image is corrupt or known format"
echo "$error"
fi
|
Scripted readers of any form of "identify " output, should do so in a case in-sensitive way, for
backward compatibility between different versions of ImageMagick.
|
compare
-- Look for Differences
All current information on this is on the
Image
Comparison Page section of IM Examples.
display
-- Slideshows of Images
The "
display
" program is designed to display a image, or sequence
of images in the form of a looped slideshow. It is not designed for a
carefully orchestrated and timed animation of images, for that use the
"
animate
" command.
Each image will be displayed in a window sized appropriately for the image,
unless other options (like window "
-geometry
", see below) override this behaviour. The image will
also generally be displayed on a checkerboard background so as to show the
effects of any transparency the image may have (see below).
Remember this is NOT designed for the display of an animation, but mean as a
slideshow of actual images. As such some caution may be needed when using
display in a scripting program.
Image Display Time
By default a delay of approximately 2 seconds is used on top of whatever delay
the user specifies using the "
-delay
" setting. However you can make it wait for user input
(spacebar) by using the option "-delay 0".
However those defaults can be override by the images themselves, depending on
there file format. As such animation formats like
GIF and
MIFF could result in either a
pause, or a 2 second plus the images meta-data delay setting. It is thus
recommended that you always set a "
-delay
" as appropriate (remember "
-delay 5x1
" will
delay 5+2 or about 7 seconds).
The same goes for the "
-loop
" setting. By default "
display
" loops forever
("
-loop 0
") but image formats like
MIFF or
GIF can override this so as to
cause it to exit after last image in the loop.
Note that "
display
" will not handle any
GIF Animation Settings so frames are not
disposed of, and virtual canvas sizes and offsets are ignored. In other words
you will see the raw partial images in a GIF animation, not the correctly
overlaid image. It does provide a "
-coalesce
" option to clean up
such animations for display purposes.
Transparency Handling
Images containing a full alpha channel (EG PNG and MIFF formats) will be
overlaid onto a 'checkerboard' background pattern, so as to let you see the
effects of any semi-transparency, such as shadow effects.
You can change that by selecting a different background with
"
-texture
" such as...
display -texture granite: test.png
display -texture xc:black test.png
|
Images with a palette (or boolean) transparency, such as GIF and PNG8 formats,
is displayed with a the current 'transparent color' that was used to represent
transparency in the color table. That is a generally random color may be used
(typically black) rather than the default checkerboard pattern. This could be
regarded as a bug, though technically it isn't.
However if you like display to handle such images in the same way as other
images containing transparency information, you can remove the palette
meta-data before feeding the image to "
display
" using the
following commands to change the internal style for the image output format.
convert image.gif -type truecolormatte miff:- | display -
|
Alternatively, just about any operation that modifies the image being
displayed will also remove the existing palette meta-data. As such some
"
display
" options can be used to remove the palette. For example
using "
-coalesce
".
display -coalesce image.gif
|
This has the added bonus of cleaning up GIF animation optimizations that may
be present. Though for multiple, unrelated images it could have other
undesirable side effects.
Yes these methods are clumsy, but they work.
Display Output Size
Display will not scale an image to fit it to the X window display. The window
size will be adjusted to fit each image, unless set using the "
-geometry
" setting. That
setting can also be used to fix the windows position on the X window display.
Images which are larger that the screen, will also not be resized, but
will overflow the screen, display will however also provide a 'scroll
window' to let the user slide around the image.
This can be painful when viewing a modern high resolution digital photo.
To limit display to say a 800x600 pixel area (only resize smaller, never
larger), use...
display -resize 800x600\> photo.jpg
|
For JPG images you can speed up the image read by using a "
-size
" setting
display -size 1600x1200 -thumbnail 800x600\> photo.jpg
|
If you want to know your X windows display size use "
xdpyinfo
"
though that is not strictly IM specific.
xdpyinfo | grep dimensions:
|
Note you should use a slightly smaller size than the returned display size to
allow for window decorations.
If the image is from a modern digital camera you can also use "
-auto-orient
" to correct the
camera rotation of the displayed image, using the EXIF meta-data in the image
file format.
If you don't want menus, you can turn them off using the "
-immutable
" setting to
"
display
", so it knows not to allow editing.
Scripted use of Display
With all these in mind, the following is my recommendation for using
"
display
" to display results from a complex shell script...
display -delay 0 -loop 1 -coalesce -resize 800x600\> some_random_image
|
Display Alternative
An alternative display method (other than using "
animate
", see
next) is to use the simpler "
x:
" output image format (See
display output format).
This method does not provide a backdrop window, menu options, or other
controls. It just simply displays the images one image at a time.
However be warned that displaying images using this method will only allow
BOOLEAN transparency, due to the old limitations of X window displays. That it
is the transparent parts will be either completely transparent or opaque. As
such edges of some images will look bad, and semi-transparent shadows may not
be shown correctly. Better to use "
display
" when transparency is
involved.
If you do want to just simple 'display' the resulting image the special
'
show:
' or '
win:
' output
Spawning Delegate will do the same thing
by runing the "
display
" command on the
output image, and exiting.
None of these techniques is recommended when the image contains transparency.
animate
-- Show an animation of images
In many ways "
animate
" and "
display
" are extremely similar.
However "
display
" only shows the images
in the given image file 'as-is' without change, adding an minimal 2 second
pause between each frame for user input.
"
animate
" on the other hand will apply any
GIF Animation Settings that are saved
with the image, and only display each image according to its 'time delay'
settings, looping back to the start to repeat the animation. In other words
"
animate
" 'animates' animation formats properly where "
display
" does not.
However because of this, the virtual canvas of the first image will control
the output image size, and other image will be overlaid into that image area.
Of course as the images are animated, you do have a fine control of the image
display timing, using options such as "
-delay
". The command also has an
extra argument "
-pause
"
to add an extra pause at the end of the animation loop, beyond whatever the
final frames "
-delay
"
setting specifies.
For example you can use "
animate
" to generate a
Flicker Comparison of two very similar images,
using something like..
convert image1.png image2.png -scale 400% miff:- |\
animate -delay 50 -loop 0 -
|
I have written a script to take advantage of this method called "
flicker_cmp
", and find it extremely
useful to pickup very subtle changes in pixel intensity that I would otherwise
miss.
stream
-- pipeline processing of massive images
"
stream
" is a special program that is designed to handle
extracting a portion of a very large image file format. It is the only such
program within ImageMagick, all others read the images completely into memory
before processing (the exception is JPEG images via the "
-size
", as this is an option
provided by the JPEG delegate library).
However "
stream
" will only output the raw color bytes of the
image (RAW format) as defined by the image depth.
You can select a portion of the image with the "
-extract
" setting. And you can
specify the depth of the raw bytes with "
-depth
" setting. And finally, you
can select which color channels to extract using the "
-channel
" option.
For more information and examples see
Really
Massive Image Handling.
import
-- read images from the on screen display
The "
import
" command is a special program that can be used to
grab and extract images from an X windows display.
For example lets get it to grab and print a window you select from your
display...
import -page A4 -gravity center ps:- | lpr
|
It is actually rarely used as the special file format "
X:
" also provides exactly the same functionality
from within the convert command.
The only difference between the two is that "
import
" has more X
window specific settings than the "
X:
"
format, such as specifying the display, screen, and/or window ID, the image is
to be grabbed from.
Other options include controls display 'beeping' and repeated snapshots.
If no specific window is specified, the mouse can be used to select what parts
of the display the user wants to grab as an image.
- If a single mouse click is used the whole window clicked in is grabbed and
returned as an image. Note that if any other windows on the display is
obscuring part of the window selected, then you will grab an image of the
obscuring other windows are obscuring the selected window being grabbed.
- A click in the root window, or selecting "
-window root
" will
return the whole screen.
- If a mouse click and drag is used a Cropped
section of the whole screen is returned, which of course also means the
location (virtual canvas offset) on the whole display (virtual canvas, or
page, size) is also 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 window title,
or a X window ID, which you can find using the X window utility
"
xwininfo
". You can also cut down the area of the selected window
using "
-extract
".
See also the special input format, "
X:
" as an alternative to using "
import
".
Note to import from the Windows clipboard use
convert clipboard:myimage image.png
and not "import"
conjure
-- IM experimental scripting language
Was originally designed to allow scripted Imagemagick use, with the use of
multiple image lists, but the improvements made to IM v6
"
convert
" has seen this experimental API fall into disuse.
It is an XML based language. Though if you want XML, SVG may be
better for your needs.
In my opinion, using the "
conjure
" script is probably better and
easier when dealing with multiple image sequences. And is being used, though
not very widely, due to lack of examples and support by users.
Image Sequences or Lists...
One of the most important points to remember with ImageMagick, and one that
confuses both new users and experienced users, is that...
ImageMagick works with Ordered Lists of Images, not single images
That is IM deals not with just one image, but potentially a ordered list of
images, be they separate individual images, a set of images that layer on top
of each other, or the frames of an animation.
Also in general all image operators will be applied to
all the images in a
sequence. This is true whether you are using the command line, a higher
level programming library such as 'MagickWand', or the lower level programming
APIs. This was also true in previous versions of IM.
As such if you use a "
-draw
" operator, it will not only draw on the last image in the
sequence, as many new users would assume, but it will draw onto
all the
images in the current image sequence, and does so, one image at a time.
Image Layering Operators, such as "
-coalesce
" and "
-layers
" will replace each image in the sequence with a new image
modified according to the other images in the sequence. It may even add or
remove extra images!
Also Image List Operators, like "
-append
", "
-mosaic
", and "
-fx
", will replace ALL the images in the current image sequence
with the resulting combined image. That is it will destroy all the source
images that were in memory, unless a "
-clone
" has been made (see
Image Sequence
Operators below).
Finally when a new image is read in or created, IM only adds that new image to
the end of the current image sequence (which always exists). Some formats
(like
GIF) may actually add multiple images to
the current image sequence, unless "
[index]
" option is
added to the input filename, to limit what is read in.
When saving images, IM will save the whole image sequence that is in memory at
the time of writing. If image format allows it IM will write ALL the images
into a single file. If the format does NOT allow multiple images (for example
JPEG), it will write the images into separate files (See
Writing a Multi-Image Sequence below).
Parenthesis -- processing images 'on-the-side'
With the formalization of the command line options, the processing order is
now exactly predictable, and it has also become possible to add parenthesis
(or brackets) to the image processing. This has been a desired feature by IM
users for a long time, and allows you to do things never before possible in a
single command.
The opening bracket '
(
' will in effect start a new image
sequence, that all enclosed operators will work on. The matching close bracket
'
)
' will then add the resulting image sequence (which may be more
than one image, or none at all) to the end of the previous image sequence.
In other words, using parenthesis means...
"I need to do a bit of work in a separate image sequence
before adding the results to the end of previous sequence."
It allows you to work on a sub-set of images, like a scratch pad, than add the
result back into the main image sequence without effecting the images you have
already previously read in or have been working on.
Let's look at some simple examples...
convert eye.gif storm.gif -negate +append cmd_negate.gif
| |
|
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.
|
Parenthesis must be given as a separate argument. That is you must separate
them from the other arguments by spaces. You can not add them hard up
against neighbouring arguments. In other words in the IM command line
argument " \(+clone " is wrong, while " \( +clone
" is correct.
Also in the last example that I needed to put a backslash '\ '
before the parenthesis. That is because when using IM on a UNIX (linux)
machine, parenthesis has special meaning to the command line shell. As such
I need to escape, or quote the bracket symbols, when I use them.
Windows DOS scripts do not require parenthesis to be escaped with backslash.
See Windows DOS Scripts for this and other
differences to linux scripting.
|
Parenthesis also make it possible to do something not previously possible to
do in a single "
convert
" command. Generating arrays of images!
convert eye.gif news.gif +append \
\( storm.gif tree.gif +append \) -append cmd_array.gif
| |
|
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.
Parenthesis and Settings
Option 'settings' are not affected by parenthesis, and will continue across
the parenthesis image operators, until the setting is changed or turned off.
For example...
convert -pointsize 24 \
-font Candice label:Outside \
\( label:Inside \
-font Gecko label:Inside \) \
label:Outside -append cmd_settings.gif
| |
|
Note how the first "
-font Candice
" setting is NOT reset back to
its default setting inside the parenthesis, while the second "
-font
Gecko
" is not replaced by the original font setting when you leave
parenthesis.
In other words...
Parenthesis only start and end a separate Image Sequence.
They do not limit settings,
only the sequence of images to which operators will be applied to.
As of IM v6.4.1-4 the new operational control option "
-respect-parenthesis
" can override this behaviour.
When given at the start of a IM command, it will cause parenthesis to also
save and retrieve the previous settings that have been given. That means any
settings given within parenthesis, will only remain set, until the end of the
parenthesis.
For example...
convert -respect-parenthesis -pointsize 24 \
-font Candice label:Outside \
\( label:Inside \
-font Gecko label:Inside \) \
label:Outside -append cmd_settings2.gif
| |
|
As you can see, when the parenthesis ended, the font setting was restored to
the previous 'Candice' font, instead of the 'Gecko' font that was set within
the parenthesis.
This can be most useful when you have to change a lot of setting, for just a
short time...
convert -respect-parenthesis \
-font Arial label:"This is a line of plain text." \
\( -font Candice -pointsize 16 -fill red -undercolor lightblue \
label:"A line using a lot of different settings." \) \
label:"Text is back to normal -- like Magick\!" \
-append cmd_settings_lots.gif
|
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 silently ignore
that specific image deletion.
The argument '
-25
' will attempt to delete the last 25th image in
the image sequence, but will silently do nothing if less than 25 images are
present. As such you can generate a rolling animation of 24 images
using a sequence like...
convert animation.gif new_frame.gif -delete -25 animation_new.gif
|
However the above will only roll the last 24 images, if more that 25 images
were present the first few images are left alone.
As of IM v6.3.4 "
-delete
" will not delete images that result in the numbered range
being reversed.
That means you can do something like this.
convert animation.gif new_frame.gif -delete 0--25 animation_new.gif
|
Which will delete all images between the first (
0
) to the last
25th image. That leaves just the last 24 images in the list. If only 24 or
less images are present, the given range of images to be deleted will be
effectively reversed, and the "
-delete
" operator will not delete anything.
-insert {index}
The "
-insert
" operation
is sort of the opposite of "
-delete
". It will take the last image in the current image
sequence and insert so that it is positioned at the given index.
convert font_[0-3].gif tree.gif -insert 1 +append seq_insert.gif
| |
|
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
), effectively 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
| |
|
As of IM v6.4 a "
-swap
"
with a single number will swap the last image with the number given.
That is "
-swap 1
" is equivalent to a "
-swap -1,1
".
convert font_[0-3].gif -swap 1 +append seq_swap3.gif
| |
|
-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 separated list of images, or a
range of indexes of the form '
{index}-{index}
'.
convert font_[0-2].gif \( -clone 1-2 \) +append seq_clone_range.gif
| |
|
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'), rotate the images
colors from blue to red, then replace the original image with the modified one
by first "
-delete
" it
and "
-insert
" the new
one.
convert font_[0-3].gif \( -clone 1 -modulate 100,100,166 \) \
-delete 1 -insert 1 +append seq_update_1.gif
| |
|
Another way that seems to have become more common is to "
-swap
" to replace the original
image, then "
+delete
"
the old image that is now on the end. This only requires you to give the
image position twice, instead of three times. Once to extract, and once to
replace.
convert font_[0-3].gif \( -clone 2 -modulate 100,100,166 \) \
-swap 2 +delete +append seq_update_2.gif
| |
|
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. Alternatively you can
pipe the image list into a "
display
" or
"
montage
" command to view the results.
Of course you would normally delete the temporary working images when
finished. If you have a lot of such temporary images, you can also just
"
-write
" the one final
image, then junk the rest using the the "
null:
" image file
format. See
Null Image format for an example of
this.
Alternatively you can delete or remove the working images as you process and
finish using them, in which case you often don't have much to clean up when
finished.
For example, here I follow the same image process I used above, to process a
fancy label. This time however I merged many operations together into common
image sequences. Also we don't "
-clone
" the images as much, and "
-composite
" merges images to
leave just the result, there is actually very few intermediate images that
needs to be specifically deleted .
convert -font Ravie -pointsize 48 -background black -fill white \
label:'IM' -bordercolor black -border 5 seq_label.gif
convert seq_label.gif +matte \
\( +clone -shade 110x90 -normalize -negate \
+clone -compose Plus -composite \) \
\( -clone 0 -shade 110x50 -normalize -gamma 1,0,0 -matte \) \
-delete 0 +swap -compose Multiply -composite seq_button.gif
| |
|
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 coalesce and -layer operators can change an images GIF -dispose and
time -delay attributes.
* Some settings effect the way an image is saved to disk, or the meta-data
saved with the image. This includes
-loop -define -compression -quality -depth
-density -background
ASIDE:
The -set operator vs the -define setting. These are very similar but
are used and applied in very different ways.
-set
Operation that attaches/changes a specific image meta-data to image in
memory. Images often load these meta-data settings with the image
itself.
Specific Image meta-data
-set comment ...
-set label ...
-set page ...
Special Operator specific settings for special handling
-set option:distort:zoom 2
Different images can have different settings, producing different
results.
-define
Is a table of global IM settings that effect specific deep operations,
often special image format libraries. They are especially relevant to
I/O operations of images, such as JPEG, PNG and TIFF.
For example...
-define jpeg:preserve-settings
-define jpeg:optimize-coding=false
See Writing JPEG Images
The equal sign is required, (unlike -set)
This are global definitions and are not directly attached to specific
images, though may be inherited by images created or read in later.
TO BE RE-VERIFIED
For example you can
-define distort:zoom=2
with will add the "-set option:distort:zoom=2" special settings to any
image that is created or read in, after that -define.
* Operation effecting settings are not attached to specific images, but get
used as they are currently set at the time the using operation is applied.
EG: -fill -background -bordercolor -strokecolor -mattecolor
-quantize +dither -channels -size -gravity -units
-density -pointsize -depth
Some of these however can be turned off, (using a + version) which
causes the operator to retrieve the setting from image meta-data
(eg: +background falls back to the original images meta-data in present)
or some default value (eg +gravity falls back to 'None or NorthWest').
A few of these also get saved with images when written. Specifically
the GIF format will save an the -background and -bordercolor as part of the
images attributes, however these are normally ignored by programs which
read these images.
You may have notices that some setting are used in multiple places.
for example -density
* used in reading in many vector format images like
Postscript, PDF, and WMF image formats.
* also in special image generators such as label: caption: and text:
* used as part of font drawing in -annotate -draw and -polaroid operators.
* And finally some formats save the density or resolution as part
of the the image file format. For example postscript wrapped raster
images, JPEG, and TIFF.
Is it any wonder then why settings can be so confusing.
Setting/Changing Image Attributes
Image Meta-data settings are generally controlled in two ways. A direct
changing of the image metadata as they are read in. Or a modification of that
meta-data once the image has been created in memory.
For example "
-label 'string'
" will set the comment in every
image that is read in or created after that setting has been set. However
"
-set label 'string'
" will change the 'label' meta-data
of all images that are in the current image sequence.
The reason for the two methods is a historical backward compatibility and
convenience. Basically "
-label
" has traditionally been set
BEFORE the image it is applied to has been read in. Also it only effects
images that are read in while it is set.
FUTURE: Move montage list examples here.
convert -label one image_one.png \
-label two image_two.png output_image_list
|
The "
-set
" operator will
however changes ALL the images that are in the current image sequence,
including ones previously read in. Thus to use it you must use parenthesis to
limit what image you are applying the option to.
convert \( image_one.png -set label one \) \
\( image_two.png -set label two \) output_image_list
|
You can un-define the setting using "
+label
", in which case the
label meta-data will come from the image itself, if present. If the image
doesn't have a label, IM falls back to a logical default, in this case the
empty string.
This same idea also goes for all the other option that set image meta-data
on input. This includes...
"
-page
",
"
-dispose
",
"
-delay
",
"
-comment
".
The virtual canvas size and image offset setting (page) however also has a
special 'set' operator "
-repage
".
For example here I use both attribute setting methods to create a
Montage...
montage -label Read eye.gif \
-label News news.gif \
\( storm.gif -set label Storm \) \
\( tree.gif -set label Shelter \) \
-tile x1 -frame 5 -geometry '60x60+2+2>' montage_label.jpg
|
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 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.
Alternative to "
-set
"...
In IM there is only one other way of changing an images attribute once it is
already in memory, and that is by having IM re-create that image from a
in-memory image register (see the special "
mpr:
" 'file' type).
For example here we take an image with a 'Bad' comment, that is in memory,
and replace the comment with a 'Good' one...
convert -comment Bad input_image \
-write mpr:register +delete \
-comment Good mpr:register output_image
identify -format "image comment = %c" image
|
This works, but is extremely awkward and painful to use, especially when
dealing with multiple images such as an animation. In fact this is the only
way to change meta-data in images in IM version 5.
Page, Repage, and Image Offset Control on the Virtual Canvas
The 'page' or 'virtual canvas' settings primary purpose within IM is to define
how a the 'real' part of an image, (the part that actually contains color
pixel data), fits in a larger context of a 'canvas'. This is especially
important when multiple images are involved and need to be positioned relative
to each other for
Layers of Multiple Images and in
GIF Animations.
It is also used, (and hence its name of the term 'page') to define where an
image fits on a larger physical pice of paper or 'page', in
Postscript or in generating image of a 'page'
of
Text.
While it is most often used for
Layers of Multiple
Images and in
GIF Animations, it
is also involved with remembering the original positions of images when
Cropping, and
Trimming
Images, as well in
Multi-Image Sequence
Alpha Composition, and in
General Image
Distortions.
Now the attribute defines two separate parts a 'virtual canvas' or area,
defining a larger space in which the image exists, and the 'offset' or
location within that 'canvas' where the actual image is positioned.
Under Construction
Controlling an images 'page' or 'virtual canvas' meta-data...
As discussed above -page is a global setting for image being read or created,
while -set page will specifically assign a new page or virtual canvas
attribute to an existing image. However a third special option has also been
provided that adjusts the image virtual in very specific ways.
The -repage operator will do the following, in response to the the argument
given.
+repage
Reset the image virtual canvas to the actual image itself. That is just
clear any virtual canvas that the image may have. This often important
after applying the image sub-diving operators -crop and -trim.
It is especially important in removing virtual canvas size and offsets
before saving to the GIF or PNG image file formats, as many browsers use
the canvas/offset information as part of the image display.
-repage WxH
change the existing images virtual canvas size, but do not reset the image
position on that canvas. Note both -page and -set page will reset the
images location to +0+0.
-repage +X+Y
Just move the image on the virtual canvas to this absolute location
without changing the images canvas size
-repage +X+Y\!
Do a relative move of the image on the virtual canvas by adding the given
numbers (positive or negative) to the images existing offset position.
-repage 0x0
Attempt to find the best virtual canvas size that contains the whole
image. This however will fail for images with a negative offset as there
is no way to specify a virtual canvas with negative components. To avoid
problems it will use the size of the actual image as the smallest canvas
size possible. That is it will never assign a virtual canvas with a zero
dimensions.
-repage 0x0+X+Y
Move the images offset then resize the virtual canvas to best fit the
images new location.
-repage 0x0+0+0
Equivalent to a +repage, +set page or -set page 0x0
-repage WxH+X+Y
Equivalent to a "-set page WxH+X+Y". That is just assign the given values
directly.
Note the use of a '!' flag will make the given offset a relative displacement
to the images current offset. That is a '-repage +5+0\!" will move the images
offset 5 pixels to the right, without modifying the virtual canvas size.
Caution is required in giving an image a final negative offset position
as the GIF file format can not handle this, and resets it to zero if negative.
Also some browsers go crazy when given PNG images with negative offsets.
What virtual canvas information is saved with an image is format dependent.
JPEG like most image formats do not save virtual canvas information
at all. The information is just ignored.
GIF will save the size of the virtual canvas and offsets as part of its
GIF animation handling. However it will not handle negative offsets.
Any negative offset will be reset to zero on save.
PNG will save offsets and even negative offsets but does not normally
save the virtual canvas information. However PNG images saved by IM
will contain a extra profile attribute to preserve virtual canvas size
info for use by later IM commands. If IM does read a PNG image without
this IM specific attribute, it will set the image virtual canvas to
the best size to show the whole image (as per a -repage 0x0)
Some formats like GIF and PNG save virtual canvas information, others like
JPEG do not. All of the above formats have there own limitations for virtual
canvas information. Only the internal MIFF file format does not have any such
limitations.
Note that "
-page
" has
special meaning for "
text:
" and "
ps:
" image
generator operators (See
Text: Multi-line Text
Files and
Ps: Postcript formated Text and
Graphics). As such its normal canvas size and offset meaning are not used
during the creation of these images.
Special 'Out-of-band' Settings
-set option:{operator}:{setting} {string_value}
For example -set option:distort:viewport {geometry}
These 'option:' settings override the normal internal working an
behaviour of operators, and are also usable by used for %[...] type
escapes of special temporary working meta-data.
Users can also create random option settings that can be later
used by Percent Escapes. See User defined option escapes
This is especially important for passing image meta-data from one image
for later use in another image, as labels, or annotations.
-define {coder}:{setting}={value}
For example jpeg:optimize-coding=false
The -define settings can override the normal behaviour of specific
image file format coders. That is, specific settings for specific coders
that go beyond the ordinary coder settings such as
-type -quality -compress -interlace -sampling-factor -density
For more examples see JPEG Write Settings.
Image Storage Color System (Colorspace)
The primary purpose of "
-colorspace
" operator is to change the way IM stores an image
within memory.
Normally each image has 3 (or 4) channels of image data. The current 'color
space' of an image determines what the data of each channel represents. Now
normally the channels are named 'Red', 'Green', 'Blue', as that is normally
the type of image data that is stored in those channels. However that is not
always the case.
Don't think of the 'R' or 'Red' channel as being red, think of it as 'channel
1' whcih could contain data for 'red', 'hue', 'cyan', or other things depending
on the colorspace of the the image. 'Red' is just a label for the channel
typically used for 'red', or the first channel.
As the second most common colorspace used is CMYK, the same 'RGB' channels also
has an alternative naming of 'Cyan', 'Magenta', and 'Yellow', though they refer
to the same set of channels as used for RGB images. A special fourth color
channel is also added for CMYK, for 'Black' (note that K = blacK).
This basically means that the color channel for "
Green
" actually
refers to the exact same color channel as would be used for
"
Magenta
". Whether the data itself is 'green' or 'magenta'
depends NOT on the name of the channel, but the 'colorspace' of the image in
memory.
There are two operators that allow you to control an images colorspace...
The "
-set colorspace
" (Add
IM v6.4.3-7) will change just the in-momory images 'colorspace' setting. that
is it can convert a RGB image into a HSL image but without changing or
modifying the actual pixel data that the image is using. The most typical use
of this is when
Combining Channel Data to
set what is the final colorspace of the combined image.
The other more common control is the "
-colorspace
" operator. This
not only sets the images 'colorspace' but will also map the image's pixel data
from the old colorspace into the new colorspace, changing the stored data
appropriatally.
For example here we separate the color channels of the built-in
"
rose:
" image as RGB, which is what the image is stored as
normally in memory.
convert rose: -separate rose_RGB_%d.gif
|
But if we ask IM to re-map the image's pixel data into a CMYK colorspace
representation, then we can extract gray-scale copies of channel data in that
image representation.
convert rose: -colorspace CMYK -separate rose_CMYK_%d.gif
|
|
While most operators within IM work correctly for images with CMYK and CMYKA
color channels, some do not. This is particularly the case for the
"-draw " operator, which
does not understand the 'black' channel. This is being fixed as they are
found. For example, blur and resize handles these type of images correctly,
and as of IM v6.3.3 rotates also handles that colorspace.
Report any CMYK operational failures to the IM Bugs Forum. Typically it is the black channel that breaks during
some image processing operation.
|
Note that a '
Gray
' colorspace only faked by ImageMagick and
remains represented by three RGB color channels. All three channels will
however contain exactly same '
Gray
' channel data, instead of just
one channel, until the image is modified.
convert rose: -colorspace Gray -separate rose_Gray_%d.gif
|
For more detailed examples of extracting the individual channels from image
formats see
Separating Color Channels.
Image colorspaces involving a 'Hue' can be extremely difficult to work with,
as the 'Hue' channel is circular (using modulus mathematics), that wrapps
around from maximum to minimum at a pure 'red' hue.
For example, notice the sharp black and white boundaries that exist for
the first 'Hue' channel image for this HSL representation of the built-in rose
image.
convert rose: -colorspace HSL -separate rose_HSL_%d.gif
|
|
ImageMagick itself does not have a good internal understanding of Hue, and
especially of color distances involving a hue color representation. This
has proven difficult to solve, especially for important tasks such as Color Quantization and Dithering.
|
On top of the 3 (or 4) color channels, an image also has an optional
transparency channel. Internally this is currently represented as a 'Matte'
channel with '0' for opaque and 'MaxRGB' for transparent. See the next
section
Controlling Image Transparency for methods to
control this important optional data channel.
Of course converting image colorspaces is actually better done using
Color Profiles which define the colors
and gamma corrections used in images, when saved. But only a few image file
formats understand and use such profiles.
For more information on different color spaces see Wikipedia,
RGB color model,
CMYK color model,
HSV (HSB) color
space,
HSL color
model,
YUV color space.
Controlling Image Transparency
The transparency channel of an image is completely optional, and often requires
special handling separate to the normal 'color' channels. See
Image Color Space above.
The existance of a transparency channel can also effect how the various
operators treat the other color channels, generally because a
fully-transparent color should often be completely ignored by an operation.
This this was not the case you get 'Black Halos' around images, such as was
seen in major IM Bugs in the early days of IM v6. For example the
Resize Halo Bug, and the
Blur with Transparency Bug.
There are two operators that allow you control the transparency channel of an
image in memory. The older one is "
-matte
" while a newer one with a lot more methods is "
-alpha method
".
The newer "
-alpha
" methods
are now the recommended method of control, though most IM Examples still show
and use the older "
-matte
" version.
Here are the various "
-alpha
" methods and examples of how they effect images and there
transparency.
Off or "+matte
"
This is just a simple switch on the image, as turns off any effect the
transparency has on the image. For example lets take a PNG image of a
'cresent moon' image (see right), then turn the image alpha channel off.
convert moon.png -alpha off alpha_off.png
|
Note that the moon shape completely vanished when the transparency was turned
off, though that is actually rarely the case. Basically even the 'transparent'
areas have color, which is just not normally visible, in this case the hidden
color was the gradient that was used to help create moon in the first place
(see
Copy Opacity Example where the
this image was generated).
This hidden color could be anything, from a simple '
GIF Transparency Color, that the GIF format
uses to represent transparency in its color table, to garbage colors left
behind during the images creation as above. Most typically the transparency
color is a pure black for any pixel that was fully-transparent (a way from the
edge of the original object in the image.
Note that while the transparency channel has been 'deactivated' or 'turned
off' like a simple switch, the data itself has not been cleared or removed
from the image that is in-memory. It is still present, just unavailable at
this time.
Be warned that saving the image with the transparency data turned off, will
not save any transparency data to the image file format, and that data will be
lost.
Also as many file formats do not allow transparency (such as JPEG), these file
formats automatically do the equivelent of a "
-alpha Off
".
The "
+matte
" operator is
an older command that is exactly the same as "
-alpha Off
". That
is it just turns off the transparency channel.
Note that this method is often required when using a gray-scale mask image
with the
CopyOpacity Alpha composition
method.
On
The '
On
' alpha method is also just a switch which just simply
turns on the transparency data again. As before it is a simple switch that
just 'activates' the transparency data channel. Any existing transparency
data is not modified, though if the image did not have any previous data, the
data itself is initialized as fully-opaque.
For example here we turn '
Off
' the transparency data, then turn
it back '
On
, reproducing the original image.
convert moon.png -alpha off -alpha on alpha_on.png
| |
|
Note that this is NOT the same as the older "
-matte
" option (see the
'
Set
' method next), and in fact this option is should not be
needed to be used very much, except in special situations.
Set or "-matte
"
The '
Set
' alpha method is the same as the "
-matte
" option. This not only
ensures that the image has a 'transparency' or alpha/matte channel, but if the
alpha channel was NOT currently 'active' it will clear it to be fully-opaque
(See '
Opaque
' next). This is typically used after reading images
which may not have an alpha channel, such as JPEG, my later processing of the
image will need one.
So repeating the previous example with this method we will see that the image
remains opaque (with the colorful background), even though the alpha channel
had previously existed.
convert moon.png -alpha off -alpha set alpha_set.png
| |
|
This is the recomended way of ensuring an image has an alpha channel after
reading it into memory.
Opaque
This method not only ensures the alpha channel is 'active' but that it is also
completely opaque, regardless of if the image had transparency 'activated/on'
or 'deactivated/off'.
As such the last example could have also been achieved using...
convert moon.png -alpha opaque alpha_opaque.png
| |
|
The original 'shape' of the image can no longer be recovered after this
operation.
Transparent
Similarly this ensures the alpha channel is 'active' but fully
transparent.
convert moon.png -alpha transparent alpha_transparent.png
| |
|
The color data of the image is still present, so turning off transparency
afterward will again show the images existing colors.
convert moon.png -alpha transparent -alpha off alpha_transparent_off.png
| |
|
Also as before the original 'shape' of the image can no longer be recovered
after this operation.
Extract
The '
Extract
' method will simply copy the 'alpha' mask of the
image as a gray-scale channel mask.
convert moon.png -alpha extract alpha_extract.png
|
Note that fully-opaque is white, while fully-transparent is pure black.
However as the image contained some semi-transparent pixels along the edges
(for anti-aliasing, providing the images shape with a smoother look) there
will be some gray colors in the above output.
The alpha channel of the image is also turned off or 'deactivated' by this
method, but it is not cleared, so turning the alpha back on will re-create a
shape mask of the original image.
convert moon.png -alpha extract -alpha on alpha_extract_on.png
| |
|
However while the above looks 'white' the edge pixels will be various shades
of gray. We can see this if we now flatten the image onto a white background.
convert alpha_extract_on.png -background white -flatten alpha_edge.png
| |
|
These 'gray' pixels are actually used to good effect in
Edge Outlines from Anti-Alised Shapes to
generate a smooth edge or outline from a image shape.
This side-effect of saving the alpha channel, has particular benifits when
Using the
Shade Operator, which does not
understand or use the alpha channel of an image. See the sub-section,
Masking Shaded Shapes.
Copy
The '
Copy
' method is the reverse of '
Extract
', and essentially performs a
CopyOpacity against itself. That is it
will turn a gray-scale image (regardless if its alpha channel is enabled or
not) into a shape mask image.
convert alpha_extract.png -alpha copy alpha_copy.png
|
It does not matter if the image had an existing alpha channel or not, all it
does is create the images transparency from the image grayscale values.
Once you have a shape mask, you can use various
Color Tinting or
Duff-Porter alpha
composition methods, to color it. For examples of using a shape mask see
Masks as Colored Shapes.
Shape
To make use of a greyscale image easier, the '
Shape
' method not
only creates a shape mask, but will also color it using the current background
color.
convert alpha_extract.png -background Yellow -alpha shape alpha_shape.png
|
This means you can very quickly color a greyscale mask simply by shaping the
image, then flattening it onto a different background color
convert alpha_extract.png -background Yellow -alpha shape \
-background Blue -flatten alpha_color.png
| |
|
Of course a faster and better way to map a black and white to specific colors
is to use the more specialised
Level
Adjustment by Color which will do the color gradient replacement without
requiring transparency to be enabled.
convert alpha_extract.png +level-colors Blue,Yellow level_color.png
| |
|
Palette Channel
Also optionally present is a 'color palette' map of the image may be defined
which represents a list of the colors the image has been color limited to.
This map could have been read in from the images original file format (such as
GIF), or has been color reduced to (via
Color
Quantization or user defined a using
Pre-Defined Color Map). However if the image contains any color not
present in this map, that map is then regarded as invalid.
The 'color palette' is however stored in the same channel as 'Black' as used
for CYMK images. and because of this IM can not color quantize CYMK images.
Such images will be reduced to RGB instead. You can however quantize CMY
colorspace images instead, then remap those back to CMYK.
Image Type when Reading and Writing
The "
-type
"
operator/setting defines the style or color space to use when an image is
being read in or written out, to ensure the resulting image (in memory, or in
the image file) is what you expect it to be. As part of this, it may do some
"
-colorspace
"
operations at the time of the file I/O, though only to ensure the image is in
a form that was expected.
For example "
-type
" has a
special '
bilevel
' setting that can be used convert and save
images as a two color monochrome image for some image formats. Similarly
'
TrueColor
' and '
TrueColorMatte
' can be used force a
TIFF image to be saved as a full color RGB
image even if the image is actually purely gray-scale.
Other settings include '
GrayScale
' and
'
GrayScaleMatte
' which will ensure the written image is
gray-scale only (without or with transparency, respectively). Or
'
Palette
' to force the use of a indexed color map in formats that
support this option, such as
PNG.
During reading of image file formats a "
-type
" setting of
'
TrueColorMatte
' will force a
JPEG image being read is has a 'Matte' or 'Alpha' channel added for its
in memory storage, even though the
JPEG format
itself can not handle transparency.
When writing to a
PNG file format
setting a "
-type
" of
'
Pallette
' will force it to use a color indexed
"
PNG8
' internal image format. Simularly using
"
BiLevel
" will force IM to dither color images to black and white
for most image file formats.
Unfortunately the exact meaning and capabilities of "
-type
" depend on the specific image
format you are reading or writing. See the various
Image File Formats example areas. For specific PNG examples see
PNG output formats.
Quality and Depth
These two terms are often talked about in Mailing Lists and in these example
pages, so I'd like to explain them a little.
Quality is a compile time
setting in ImageMagick, and is used to determine the size of the values use to
store images in IM memory and during processing. Basically it means the
Quality of Processing that a specific IM was compiled for.
The
Depth is the size of the values used when an image is either read
or saved to/from an Image File Format. It is as such more highly variable.
and controlled by the "
-depth
" setting, or by the original 'depth' of the image that was
read in. more on this in a moment.
Remember...
Quality is 'in memory' value size, and is compiled into IM.
Depth is file format value size, and is variable.
Depth - file format bit depth
Now most image formats are of depth 8. That is they use 8 bits (or a value
from 0 to 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
GIF format, or using a
special profile for a specific number of colors in the color table in a
PNG8 image. However only a single color
transparency is implemented in IM bit image formats at this time.
In general...
- 24 bit images are : 3 x 8 bit depth values 3 color channels only
- 32 bit images are : 4 x 8 bit depth values 3 colors + Alpha channel
- 8 bit images are : 8 bit color mapped image, with 256 color limit
Because of this a lot of people install IM using a 'Q' or Quality level of
depth 8, which requires less memory and processes images faster than a more
normal Q16 version of IM. These Q8 versions work well, and are good for
generating simple images, annotating, or overlaying images. However a low
quality while faster and more memory efficient, falls does when you start
using complex multiple sequences of operations that could produce serious bit
level effects (see below).
Quality - the in memory bit depth
Remember,
Quality is a compile time setting in ImageMagick, and is used
to determine the size of the values use to store images in IM memory and
during processing. It can not be changed, except by re-compiling ImageMagick
from sources.
A 'Q16' ImageMagick thus will use twice as much memory as a 'Q8' version of
ImageMagick, and depending on your CPU, could be slower, though on today's
processors that is not very likely. Similarly you can compile 'Q32' and 'Q64'
versions, though these are not very common. Also see the new
HDRI compilation quality option below.
A 'Q16' ImageMagick also allows you to save more bit information for each
pixel value. That is color values are saved as integers ranging in values from
'
0
' to '
2^quality-1
'. That last value is
known in IM programming as the current 'QuantumRange' (or the older obsolete
name 'MaxRGB').
The higher the Quality Setting, used when compiling IM, the more precise the
color values used to store the image in memory. That means that if in
processing an image you generate a lot of very small, slight variations in
color, then those variations will be preserved in the in-memory storage of
ImageMagick. In a low quality IM however those effects can expand more quickly
producing unwanted color distortions in the resulting image.
Such operations include: noise filters, blurring, sharpening, averaging, or
lots of complex image composition operations. In such cases using a Q8 IM for
the in-memory bit depth will not work well, and could create very distinct
color artifacts on the resulting image.
Of course saving the final image to a 8 bit quality image format will
'quantize' those color values back to 8 bit, but during the processing of the
image the quality is preserved, and they will not effect later operators as
much.
Some formats are available that preserve the higher quality level information
used by IM. For example the
MIFF IM format, the
enumerated pixel
TXT format, as well as the
NetPBM image formats. However a Q8 version of
IM while it will let you output a 16 bit depth image, will not does not
improve the overall quality of the saved image, as that information is not
available.
|
If IM reads an image from a 8 bit quality image format, the images 'depth'
will be set to 8 bit, and by default it will save the image at 8 bit depth,
even if you process the image using a 16 bit 'quality'. This is true even
if you save to a format such as MIFF.
That is the original image 'depth' will be preserved unless you change it
using the "-depth "
setting, before saving. As such reset that setting if the depth of the
saved image is important.
|
HDRI - floating point quality
IM can be compiled to use a floating point values for images stored in memory,
to allow you to
perform HDRI styles of image operations. HDRI, or
High Dynamic
Range Imaging, is designed to more naturally represent our eyes ability to
see both bight and dark areas of a scene simultaneously.
The HDRI still uses same color range as the current compile-time
Quality Setting for in memory storage. That is values
still range from '
0
' to the 'Quantum Range'. But the values are
saved using floating point ('
doubles
' in C programming
terms), so 'quantum' effects from the rounding off of integer values will not
be seen. The values are also not 'clipped' when the values go beyond the
'Quantum Range' or into Negatives, though some care may be needed.
That means by compiling IM with HDRI support, (See
Enabling
HDRI in ImageMagick on the main IM website), you will not loose as much
information between processing steps as the results will be saved as a
floating point value without quantization or clipping. Using a HDRI quality
you can even process images using negative or monstrously huge values. As long
and the final color values is in the images normal value range, when it is
finally saved (depending on the image file format).
If all the colors of an image is compressed to a very small (or large) range
due to processing, the floating point will ensure there is no loss of image
quality.
Of course saving a image into a image file format that does not support
floating point values will be clipped, quantized, and even color reduced (
Color Quantization) to fit the image into that
format. As such the image may still need to be normalized before saving it to
a normal image file format.
Image formats that can handle floating point values (without clipping)
include: the IM internal formats
MIFF and
MPC, as well as PFM, and TIFF (though only a few
applications will understand TIFF with floating point depth quality). However
if you want to save the intermediate 'floating point' forms of the images, you
may need to give a hint to IM that you want to preserve the floating point
values in the saved image by specifying the special option "
-define
quantum:format=floating-point
".
|
The floating point HDRI will be required to make full use of the new Fast
Fourier Transform (FFT) Filtering operators that are currently under
development.
|
FUTURE: OpenEXR reference
Examples of HRDI images
Image Density
While in-memory
Quality and file format
Depth specifies the color 'resolution', the
Density
of an image is the spatial (space) resolution of the image. That is the
density (expressed as dpi, or dots per inch) of an image define how far apart
(or how big) the individual pixels, and thus the overall size of the image in
real world terms.
The density of an image is completely irrelevant to the actual images pixel
size. It is just a set of numbers stored with the image to tell output
devices such as printers and displays how many dots (or pixels) per inch the
image should be displayed at, OR for vector formats like postscript, pdf, MWF,
the pixel scale to draw the image at.
You can set the resolution or density of an image as it is being read into IM
by using the "
-density
" function,
before reading the image, or using
"
-set density
" after
reading the image in (it is better to do it before reading).
A 200x200 pixel image at 600 dpi will thus be displayed in 1/3 inch square in
real world terms. On the other hand a much smaller 72x72 pixel image at 72
dpi will display in a 1 inch square, in the real world, though its spatial
quality will not be very good in comparison. That is just how it works.
A "
-units
" setting can be
used to define if the density number is expressed in the default (traditional
printing) terms of '
PixelsPerInch
' or in more modern metric units
of '
PixelsPerCentimeter
'.
Remember density or resolution is purely a number stored within an image and
has no bearing on the actual image pixel size, or the amount of actual image
data that is used to represent the image, it really only the output display
size and pixel quality, when the image is actually used on a real world
device.
Note that the "Photoshop" image editor saves an extra copy of the images
resolution into a separate profile (named '
8BIM
') in the image,
which IM will NOT touch. Thus if you change the resolution of an image with
IM, you probably should also strip the profiles from the image before loading
it back into "photoshop", or you may not see any density changes. .
For more information see the notes on the
Resample Resize Operator.
ImageMagick Operational Controls
IM also has a few special options that it uses to control its operational
working, information reporting, and for debugging purposes.
-version |
Output what version of IM, the image quality it is using,
and when was it built.
IM will implicitly exit after outputting this information.
|
-list |
This is an informational option only and will list the requested
items, then exit. That is you can not use this with any other
option, or image processing. It is purely provides for
informational purposes, especially in scripts to check input
options and if IM has certain options implemented.
The given argument defines what information you are wanting to list. For
example a list of 'color ' names that you can use, (such as
using by ("-fill ",
"-background ",
"-mattecolor ",
"-bordercolor "). While 'font ' lists the fonts
that are specifically known to IM.
Here are just some of the more interesting lists...
font |
Known fonts (IM also knows about X and PS fonts)
|
type |
file image types ("-type " )(after IM v6.3.5-7)
or the font list (before that IM version)
|
color |
known color names for various color options.
|
dispose |
all the GIF disposal settings ("-dispose ")
|
compose |
alpha compositions are available (includes internal methods)
|
layers |
what multi-image "-layers " methods has been implemented
|
command |
what command line options (both settings and operators) are
available
|
list |
what lists can "-list " list!
|
configure |
what were the configuration parameters used to build ImageMagick
|
That last 'list' setting 'Configure ' is very important, as it
will tell you what libraries, and delegates were available when IM was
built. It also includes the 'point' release number that is usually
missing from the normal "-version " output. (See Script
Version Handling for one example of using this information.
IM will implicitly exit after outputting this information.
|
-verbose |
Report extra info on some of the more complex operations.
For example "-segment ", which outputs a lot of color quantization details.
This is especially useful to generate for more detailed image
information from the "info:" and "-identify" outputs.
|
-quiet |
Don't report informational warning messages. Only proper errors
such as I/O errors, or bad options, etc.
This is especially useful for "-crop " or "-trim " and "-layers optimize " to not report 'missed images' warnings.
This will also quieten some complex image file formats that can
contain 'unknown chunks' which IM would normally ignore. For
example when IM is reading MPEG (AVI) video formats.
|
-regard -warnings |
Where the previous control option will quieten some informational warning
messages, '-regard-warnings ', will make them fatal. It also
causes IM to return a proper exit status according to such error
conditions.
It can be used in scripts to 'sanitize' image file being provided
from uncontrolled sources. That is this option will make IM fail
and exit, if when the JPEG or TIFF image was not correct, complete or
contained 'unknown' profiles.
|
-respect -parenthesis |
Causes parenthesis to not only to save and
restore the current image list but also all the current operational settings are saved and restored. Than means that when
given, any settings set within parenthesis, will be reset when the
parenthesis ends. See the examples in Parenthesis and Settings above.
|
-ping |
For the "identify" command. Im will try to avoid
completely reading and decoding the full image file format for basic
information such as the images size.
|
-monitor |
Report a percentage of processing during each stage of image
processing, especially for very large or long image processing
tasks.
In a lower level API, you would use SetImageInfoProgressMonitor() or
SetImageProgressMonitor()
|
-debug |
Report verbosely exactly what IM is doing, in various areas.
The argument is a comma separated list of options, such as...
exception |
What is IM not understanding about the command
|
cache |
See how much disk space IM is caching
|
configure |
Show IM search attempts to find its configuration files.
|
all |
Show every trace point during processing
This is very very VERY verbose and not recommended
|
annotate |
Report on font metrics when a font is used with "-annotate ".
|
For command line and API usage you can also define an environment variable
to set the debug level using actions by IM.
|
FUTURE Section on debugging...
All three of these do exactly the same thing.
-format '...' -write info:
-format '...' -identify
-print '...'
Format and output information requested as % escape strings, about the images
in memory, at this point in the current image operation sequence.
Checking on what images are present at each point...
-write x: - show the current images
waits for you to quit the view before continuing
-write show: - show the images at this point, but don't wait!
Add a new delegate, so users can....
-write montage: - show images as a montage at this point, don't wait.
Other debugging techniques....
-monitor watch IM processing the images (with percentages)
-verbose watch images read in/out and extra output from complex operators
like -distort, -sparse-color, -segment
-debug watch the internal calls within the MagickCore Library.
this is VERY verbose and rarely nessary.
if -debig is used the location of the logging output is controled by
the "log.xml" file. This is by default set to "Console". to have it save
to a fiel change <log output="console"/>
to
<log output="file"/>