- Index
ImageMagick Examples Preface and Index
ImageMagick Command Line Processing
ImageMagick Commands
Image Sequences
Complex Image Processing and Debugging
Image Attributes and Settings
- Setting/Changing Image Meta data
- Page, Repage and Image Offset Control
- Special 'Out-of-band' Settings
- Image Color Space Storage
- Pallete Channel
- Image Type when Reading and Writing
- Controlling Image Transparency
-
Off (or +matte),
On,
Set (or -matte),
Opaque,
Transparent,
Extract,
Copy,
Shape,
Background
- Quality and Depth of Images
-
Depth,
Quality,
- HDRI - Using Floating Point Image Quality
- Image Density or Resolution
-
Photoshop and Density
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 image processing operations!
For example...
convert -size 40x20 xc:red xc:blue \
-append -rotate 90 append_rotate.gif
|
![[IM Output]](append_rotate_bad.gif)
The result (in IM v5.5.7) was that the two input images were rotated
first, then appended together, producing a image like...
That is the "
-rotate"
operator would be applied BEFORE the "
-append" which is probably not
what the user intended.
![[IM Output]](append_rotate.gif)
With ImageMagick version 6, 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 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
|
|
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, an explict
-write operation is performed with this argument.
The single image in the current image sequence is written using the
given filename and image file format.
| written
|
As you can see the processing of the command line in ImageMagick version 6 is
very straight forward, and logical, making the result predictable. And that is
the point...
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.
  |
Do not expect that this legacy support will continue into IM version 7.
Plans for IM v7 include single-pass processing of command lines, which in
turn will allow for the use of reading image processing options from files
and even pipelines. However a single-pass processing technique will not
allow for the saving of operators BEFORE reading an image to apply them to.
As such they will probably produce 'no image' type errors.
|
Command Line vs API
There is a couple of major differences between a command line IM, and using
the Magick API's, such as PerlMagick, RMagick, PHP IMagick, 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 temporary (see Parenthesis and MPR:
Named Memory Registers). You can even 'clone' images from the last
'pushed' sequence. but you can't really work on two such sequences at the
same time, simultaneously.
Other language API's on the other hand allow you to have as many separate
image lists or 'wands' as you like. In fact you typically save each image
as a separate wand (sequence) for better processing and only merge the
image into one sequence as needed or as part of the final step. You can
also work on them in any order, and store them into databases or other
data structures, for sorting or later comparison.
On the command line however one single image list means you can not do
operations in just any order, but generally try to do things in a more
logical sequence, completely finishing each image processing step as you
go. Basically it means is much harder to 'go back' or to change something
later, using results from one processing image sequence to modify image
processing, of a different image processing sequence.
It is especially more difficult to merge or interleave (shuffle) two
completely separate lists of images into a logical whole. However some
techniques have been worked out, to allow you to do this from the command
line. For example see Multi-Layer
Alpha Composition of Image Lists.
- Direct Access to Pixel Data
- Again you can do 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 merge and mathematically modify pixel data of images using the
special FX Image Operator, but it is
generally limited to transforming whole images, and very very slow.
To make it easier many common operations developed by users using the FX
operator, have now been built into IM, creating things like Color Lookup Tables, Evaluate Math Functions, and Multi Argument Functions. As well as
the General Image Distortion Operator,
and some special Image Composition
Methods.
API's can manipulate images in a much more direct manner, alowing you to
DIY a unique operation much more easilly, at the full speed provided by
the API language.
- Conditional Processing
- While the IM command line interface can not easilly modify images based on
some image derived attribute. For example it is very hard to 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 of this see the well
commented Jigsaw Script.
API's on the other hand can do this type of conditional processing, while
holding all the images involved in memory, ready to continue processing
based on the specific conditions, as and when you need it.
- Looped Processing
- You also cannot just simply loop over images in a controlled manner, or
easily modify the process based on which image in the sequnece is being
handled. that is you can not simply do something different to each image
based on the image 'scene' number, or the results of previous images. For
example draw text at different sizes, or gradually blur an image, or
generate an animation sequence in the one single command.
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 the
shell script that is designed to Divide
an Image Vertically.
Alternatively, you can generate the images using a shell script loop, and
pipe the result into a final command to merge them into the final image or
image sequnece. For example of this see the shell scripts in Layered Images Examples, or the various Warped Image Animations 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. It can also
hold all the images in memory ready for the final combining step, without
pipelining, or using temporary files.
If your application needs to be able to do any of these things (though few
applications actually need to go this far) then an API may be a better choice.
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, though
it is still available and still being developed.
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 commands 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 command line abilities became
many orders of magnitude more useful.
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
a computer language (such as Perl, PHP, or C). Of course some shell scripting
knowledge is helpful, though not strictly required.
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, as it can easily 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 that
has no backup.
Now while "
mogrify" normally saves a modified image into the same
filename, it has two special options which allows it to save images into
a different file.
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 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.
For Windows Users I refer you to the
Windows Usage
section, and in particular
Windows, Batch
Processing Several Files.
If your commands start 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 final 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' \
../img_photos/anthony_* 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 use 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 as
a slideshow of actual images. As such some caution may be needed when using
display in a scripting program.
Image Display Time, Loop, and other options
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 defaults can be overridden 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) for your script and needs.
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. See the "
-loop" option appropriatally for
your situation.
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.
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.
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. 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 option is passed to
the JPEG delegate library).
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.
However "
stream" will only output the raw color bytes of the
image (RAW format) as defined by the image depth, as such you may need to pipe
the output of the extracted segemnt into convert.
For example...
stream -map rgb -storage-type char -extract 100x100+200+100 logo: - |\
convert -depth 8 -size 100x100 rgb:- stream_wand.gif
| |
|
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.
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 images,
unless
Parenthesis and
Cloned
Images were made. (see
Image Sequence Operators
below for practical examples).
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 a special
Indexing Read Modifier 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).
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 use "
-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 clone, and once to
replace the modified image.
convert font_[0-3].gif \( -clone 2 -modulate 100,100,166 \) \
-swap 2 +delete +append seq_update_2.gif
| |
|
These techniques are continued below in the next section on
Complex Image Processing and Debugging.
Complex Image Processing and Debugging
Thanks to the addition of
Image Sequence Operators
(see above), you no longer need to process images one step at a time, saving
the image and re-reading it again each time. Instead you can now simply hold
the intermediate image in memory and continue processing it. This saves a lot
of time, both in the converting of images to a file format, and in the actual
IO to save the image to slow disk.
This type of image processing commands can become very long and complex. As
such it is better to write the command in scripts, and try to place each major
operation on a line by itself for easier programming and editing. See
Hints for Better
ImageMagick Shell/PHP Scripts
For example, here I go though a whole complex processing sequence to generate
a red button on a black background.
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,-1 -compose Multiply -composite \) \
-append seq_process_fx.gif
| |
|
Each line of the convert command generates a new image, except the last line
where I just
Appended all the working images
together to output the results of all the processing steps, rather than just
the final image.
This technique lets you follow what each step (wrapped in parenthesis) of the
very complex command produced, and allows for easier debugging of each step in
of a process.
Note how it 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.
Of course you would normally
Delete all the temporary
working images. That is I would replace the last line in the above with
something like this...
-delete 0--2 seq_process_result.gif
|
Other ways of checking the results is to pipe the result into the display
command, so as to view the results on screen, instead of save it to a image
file. that is use something like this for the last line...
+append miff:- | display -
|
Alternatively instead of "
display" you
can use '
show:' which will display the resulting image on screen,
and then allow the original command to continue or exit. See
Show, Display Image Output for more information.
You actually don't even need the "
+append", in which case IM will show each image in sequence, by
pressing 'spacebar'.
You can even get fancier by using "
montage" command to view the results in a nicer way...
miff:- | montage - -bordercolor blue -border 1 -geometry +2+2 show:
|
This type of image processing also allows for easy viewing of intermedaite
images, immedatally the image has been created. Basically you can insert
lines this in between "
\( ... \)" statements.
\( +clone -write show: +delete \)\
|
IM will automatically continue processing once that intermediate image has
been output for display purposes. See
Show, Display
Image Output.
Alternativally, by inserting this line instead, you can display all the
current images generated so far at that point in the processing...
\( -clone 0--1 -append -write show: +delete \)\
|
After you have the image processing steps debugged and settled then you can
optimize the code, so that you don't use as many parenthesis steps, as well as
fewer
Cloned Images, and resulting in less intermediate
images to
Delete at the end.
Remember also that "
Image
Composition", and or "
Layer
Flattening" merges multiple images together, to leave just the one
resulting image, which can reduce the overall number of intermediate images in
memory.
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 ability of ImageMagick, to process any image, in a standard, programmed,
and automated way, using multiple steps all in the one command is what makes
IM such a powerful tool. You can script up a very complex operation, then
apply it to many 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 another example of scripting a complex images process together see the
example
Scripted 3-D bullets from
Shapes.
Also see
Hints for
Better ImageMagick Shell/PHP Scripts, on ways of improving your image
process scripting, both for easier editing, understanding, and for others
to be able to follow what you have done.
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. Not all image formats understand these image meta-data
settings, so testing with a specific Image File Format is recommended
first before making use of them.
EG: -label -comment -page -delay -density
that can be turned off (meaning they do not override images being created
ot read-in, by using + instead of -.
Their are also special 'operators' that modify these settings for images
that are already in memory. Some are specialised to provide extra
ablilities and controls.
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, -layer, -mosaic, can
adjust an images saved virtual canvas size and offset on that canvas. And
-coalesce and animation specific -layer operators can change an images GIF
-dispose and the 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
The -set operator and the -define setting 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
This is actually the same as
-define distort:zoom=2
(See below)
You can turn off (delete) a setting using.
+set label
Different images can have different settings, producing different
results.
Set items without a "options:" prefix are known as "Image Properities"
and can be known and saved in specific image file formats. The "MIFF"
file format saves all of them.
While items set with "options:" are known as "Image Attributes" and
are generally used for expert or 'out-of-band' options used by various
library options. They are not saved with images.
You can see these using a "-verbose -identify" operation or a
"-verbose info: file information output.
-define
Are global IM settings that effect image processing operations.
More specifically they effect Image File Format Coders (that is
reading and writing specific image formats). They are often special
options to the image delegate libraries being used, and 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 in -define is required for settings that take an
argument. (unlike -set)
These are actually the same as using "option:" with "-set".
That is
-set option:distort:zoom 2
is the same as
-define distort:zoom=2
This are global definitions and are not directly attached to specific
images, though may be inherited by images created or read in later,
and then used by other operators.
You can see what options are set by looking at the "Image Properities"
(-set) and "Image Attributes" (-define) in the verbose identify ouput.
* Operation effecting settings are not generally 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 -font -pointsize
Most 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 if present)
but more generally to 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 (Meta-data)
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 Color Space Storage
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 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.
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 before quantization. You can however
quantize CMY colorspace, though the results is the same as an RGB image.
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.
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.
If 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.
Alpha Off or "+matte"
This is just a simple switch on the image, which turns off any effect the
transparency has on the image. It does not actually delete or remove the
alpha channel attached to the image, it just turns off any effect that channel
has on the image. Similarly no operator will effect the attached alpha
channel while it has been turned off.
For example lets take a PNG image of a 'cresent moon' image (from a
CopyOpacity Composition example), then
simply 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 fractile canvas image that was used to create the moon image.
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. Note that
pixels close to the edge may be semi-transparent, and thus still have a valid
color that is only partially visible.
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 stored 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 as such the data
will then 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" when
the image is saved.
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, so it copys the grayscale colors, rather than the turned-off alpha
or opacity channel.
Alpha 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.
In fact the only time "
-alpha
On should ever be used is when you previously, any purposfully turned
off alpha for some reason. For example to preserve the contents of the alpha
channel before applying some specific operators, such as "
-shade". For an example of this
see
Shaded Shape Images.
Alpha Set or "-matte"
The '
Set' alpha method is the same as the "
-matte" option. This
ensures that the image has a 'transparency' or alpha/matte channel, but if it
was not present or turned off, that it will be set to be fully-opaque (See
'
Opaque' next).
In other words this operator ensures an alpha channel is present, without
modifying the look of the image in memory, as it was before the option was
run. As such on its own this operator does not show any change to the image,
but has real effects when combined with other operators.
So repeating the previous example with this method we will see that the image
remains opaque (with the colorful background).
convert moon.png -alpha off -alpha set alpha_set.png
| |
|
Basically as the the alpha channel was turned off, the "
-alpha Set' operation, turned back on, and reset
to fully-opaque. As such the image still looks the same as it did when the
alpha channel was turned off.
If applied to an image that has an enabled alpha channel, no change is
made.
convert moon.png -alpha set alpha_noset.png
| |
|
In summery, this operator should never change the current appearance of the
image. It just ensures the alpha channel is present.
This is typically used
after reading images of an unknown image file
format or source, which may or may not have an alpha channel present. This
operator will then ensure that the image does have an alpha channel (for image
formats like JPEG), but leaving any enabled and existing alpha channel alone
(such as for GIF or PNG formats).
This is the recommended way of ensuring an image has an alpha channel after
reading it into memory, regardless of image file format being read.
Alpha 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 it is sort of equivelent to turning off the alpha channel, then
using "
-alpha set' as we did above...
convert moon.png -alpha opaque alpha_opaque.png
| |
|
On older versions of IM, this was equivelent to using both "
+matte" to turn off the alpha
channel, then using "
-matte" to turn it on and reset it to be opaque.
convert moon.png +matte -matte alpha_opaque_matte.png
| |
|
The original 'shape' of the image can no longer be recovered after this
operation as the original alpha channel data has been overwritten.
Of course that is also equivelent to using "
-alpha off -alpha
set", though you may as well use "
-alpha opaque" in that
case.
Alpha Transparent
Similarly this ensures the alpha channel is 'active' but also 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.
Other ways of turning an image fully transparent is presented in
Transparent Canvas.
Alpha 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 benefits when
Using the
Shade Operator, which does not
understand or use the alpha channel of an image. See the sub-section,
Masking Shaded Shapes.
An alturntive solutions to extract the alpha channel is presented in
Extracting the Transparency Mask.
Alpha 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.
Essentually this applies a
Compose
CopyOpacity (with alpha turned off) of the image with itself.
Alpha Shape
To make use of a greyscale image easier, the '
Shape' method not
only creates a shape mask (as per
Alpha Extract,
but will also color it (using
Colorize) with
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_colormask.png
| |
|
Of course a faster and better way to map a black and white image, directly to
specific colors is by using the more specialised
Level Adjustment by Color. This will avoid
the need to enable or even modify the existing images transparency channel.
convert alpha_extract.png +level-colors Blue,Yellow level_color.png
| |
|
Alpha Background
As of IM v6.5.2-5 (and fixed for correct working in IM v6.5.2-10), a
'
Background' method was added that will set the hidden color of
fully-transparent pixels to the current background color.
Normally this color is of no consequence, as it can only be seen if the alpha
channel is
turned off, or you blur an image without
setting the
Blur Channel Setting.
However the color of fully-transparent pixels is saved with in PNG Image file
format, and for large image can significatally effect its compression handling.
See
IM Forum Discussion.
For example here I use it to set all fully-transparent pixels to
'HotPink'.
convert moon.png -background HotPink -alpha Background moon_hotpink.png
| |
|
As you can see this made no change to the actual look of the image. But if we
now turn off the alpha channel, you can see that
any pixel that was fully-transparent will now be the color specified.
convert moon_hotpink.png -alpha off moon_hotpink_off.png
| |
|
This is not the same as overlaying or
Flattening the original image over a specific background color, so as to
remove transparency. No color mixing is applied, only a direct color
replacement of ALL fully-transparent colors.
In fact it is very similar (but not quite) the same as doing a "
-channel
RGB -fill color -opaque None +channel". See
Direct Color Replacement.
Note that many other image processing operators will also convert any
fully-transparent pixels, to fully-transparent black (color
'
none'), as this is the color equivalent of a mathematical zero.
Here is a summery of some image operations that are known to do this, though
none are as direct or as fast as using this operator.
convert moon.png \( +clone -alpha off \) \
-compose SrcIn -composite moon_black.png
convert moon.png -channel RGBA -blur 1x.000000001 moon_black.png
convert moon.png -channel RGBA -gaussian 1x0 moon_black.png
|
Quality and Depth of Images
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).
The actual pixel data is then 8-bit values (0-255) which looks up the color
for that pixel from the color table. That is the 'raster' (pixel array) is
a 8-bit value used to lookup a table of colors.
In other words while an 8-bit images also have a 8 bit depth, the value is
refering to the number of bits used to store the actual pixel data, in this
case a single 8-bit value used to to lookup the color from a color table. 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 most image formats only save color values at an 8 bit depth, a lot of
people install IM using a 'Q' or Quality level of depth 8, which requires far
less memory and processes images faster than a more normal Q16 version of IM.
Often 3 or more times faster. These Q8 versions work well for general image
processing and converting, and can be used for generating simple images,
annotating, or overlaying images.
However while a low quality IM is faster and more memory efficient, it does
not work work well when you start using complex sequences of operations
involving multiple color changes, darkening, lightening, gamma or histogram
color correction, etc.. At Q8 the intermedite images in memory will remain
stored as 8 bit quality, and thus multiple operations will each introduce more
and more distortion. The result can be serious bit level rounding effects,
especially for extreme colors near white and black. (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 at least twice as much memory as a 'Q8'
version of ImageMagick, and depending on your CPU, be a lot 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, and are typically only
used in very high end image processing. 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, and not lost in later processing steps.
Operations such as noise filters, blurring, sharpening, averaging, global
color, gamma, and histogram modifications, or lots of complex image
composition operations, can all produce unwanted color errors in a Q8 IM,
creating 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.
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 while a Q8 version of IM it will let you output a 16 bit depth images,
such image will still only have information equivelent to 8 bit depth as the
quality is just not there.
  |
If IM reads an image from a 8 bit quality image format, the images 'depth'
will be set to 8 bit, and IM will normally try to save the image at 8 bit
depth, even if you process the image using Q16 version of IM. You can
override this using the "-depth" setting.
Also may operators that generate extra colors such as Image Resizing, will also reset the 'depth' of the image in memory to
the compile time quality setting, so that IM will then try to save it at a
higher depth, if posible.
|
HDRI - floating point quality
HDRI, or
High Dynamic Range Imaging, was originally designed to more naturally
represent our eyes ability to see both bight and dark areas of a scene
simultaneously. In practical image processing terms it does a lot more than
that.
Basically IM is specially compiled to use a floating point values for images
stored in memory, to allow you to perform more exact HDRI handling of image
operations, so as to prevent such operations 'clipping' the image colors at
the extremes.
The HDRI still uses same color range as the default 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)
rather than integers, so that the 'quantum' effects from rounding off values
into integers will not be seen. The values are also not 'clipped' when the
values go beyond the 'Quantum Range' or into negatives.
That means by compiling an IM with HDRI support, (See
Enabling
HDRI in ImageMagick on the main IM website), you will loose far less
information between processing steps. HDRI is thus
vital when you plan
to use very heavy mathematical processing of images, involving the temporary
use of negative values, or strong scaling to very small or very large values.
It is especially important for users that want to make best and full use of
new
Fast Fourier Transforms (FFT) capabilities,
and it is here that you will see the most examples of a HDRI version of
IM.
One important operator that should be kept in mind when using HDRI is
"
-clamp". This option
will clip the values in an image that fall outsize the normal range for
images. That is any negative value will be clipped to zero, and any value
large than 'QuantumRange' will be set to that value. It does not however
'round off' the values into integers.
Quantum Effects, HDRI vs non-HDRI
For example here I use the
Level and the
Reverse Level operators to compress the color
range of a gradient image down so they only use the values from 0 to 15, then
uncompress it again. The resulting gradient is also displayed as an image
profile (using the script "
im_profile") to make it easier to
follow.
# Using a normal non-HDRI version of IM...
convert -size 20x600 gradient: -rotate 90 \
+level 0,15 -level 0,15 level_rounding.png
im_profile -s level_rounding.png level_rounding_pf.gif
| |
|
Notice the sever rounding (quantum effects) that is now visible, forming steps
in the gradients profile. As only 16 gray-level valuse were used, you
effectivally converted the image to a color depth of only 4 bits!
And here I 'stretch' the gradient so that the original black and white color
values go well beyond the "Quantum Range", before being restored again.
# Using a normal non-HDRI version of IM...
convert -size 20x600 gradient: -rotate 90 \
-level 20% +level 20% level_clipping.png
im_profile -s level_clipping.png level_clipping_pf.gif
| |
|
You can see that a normal IM looses the information at both ends. The lower
end values gets 'burned' as values become negative, while the upper values
become 'clipped' as they go beyond the maximum 'Quantum Range' limits of the
intergers used to store the values.
Repeating these two operations using a
HDRI version of ImageMagick will
not produce any rounding, burning, or clipping of the results, but will have
a extra cost in terms of memory. Speed wise, it does not cost much, and may
actually even be faster, depending on the computer hardware.
# Using HDRI version of IM...
convert -size 20x600 gradient: -rotate 90 \
+level 0,15 -level 0,15 level_rounding_hdri.png
convert -size 20x600 gradient: -rotate 90 \
-level 20% +level 20% level_clipping_hdri.png
im_profile -s level_rounding_hdri.png level_rounding_hdri_pf.gif
im_profile -s level_clipping_hdri.png level_clipping_hdri_pf.gif
|
Clamp to Enforcing image bounds in HDRI
You can force HDRI image to be 'clipped' by the normal image value range
by using "
-clamp"
between the two level options. For example...
# Using a HDRI version of IM...
convert -size 20x600 gradient: -rotate 90 \
-level 20% -clamp +level 20% level_hdri_clamp.png
im_profile -s level_hdri_clamp.png level_hdri_clamp_pf.gif
| |
|
The use of "