ImageMagick v6 Examples --
Image File Handling

ImageMagick Examples Preface and Index
Image Formats Summary
Saving Images
Reading Images
Importing Images from special sources
Special Output File Formats (Specific to IM)
miff:   info:   null:   txt:   histogram:   mpr:   mpc:   x:   tmp:
Delegates and Coders for Image Formats
Writing a Multi-Image Sequence
Writing an Image, Multiple Times
Really Massive Image Handling

To process an image, you not only need operators to work on the images, but you also need ways to read in and write out the image in as many different file formats as possible. In this section we look at IM file formats in general.

Image Formats Summary

One of the most common uses of ImageMagick is not to modify images at all, but only to convert an image from one image format to another. In fact this was the original reason for IM's creation was this sort of image format conversion. This is why the primary IM command is call "convert".

To this end, ImageMagick can handle a bewildering array of image and file formats. Added to this array are a large number of special input and output formats for built-in test images, simple image creation, and image formats specific for programming shell scripts, and programs. For a complete list, see IM Image Formats Page on the IM web site.

All this can be daunting for a new user of ImageMagick. My best advise is to ignore most of the file formats, as you will probably never need them. Instead concentrate on what you want to do, and try to do it. If you don't know how, try to look for an example in these pages and across the web.

For image formats demonstrated in IM Examples, see Reference Index, File Formats.

Saving Images

Processing images is well and good but it can be just as important to save the results in the right way.

The last argument of the "convert", "montage" and "composite" defines the save filename, and image format for that image. Though you can also save an image in the middle of an image sequence using "-write".

To specify what file format you want to save your image, or images, you can either use a filename suffix, such as I use in just about all these examples, or prefix the filename with the string "{format}:". For example...

  convert tree.gif    GIF:tree_image
[IM Output]

If you check the resulting image you will find that the GIF image created does not have a ".gif" filename suffix. The case of the format is not sensitive, so you can use either lowercase or uppercase.

This image format specification becomes particularly important when you want to save the image to the standard output of the command (using a "-" filename). This special filename does not have a suffix, so you must tell ImageMagick what format to use. If you don't, the image will default to the original image format that the image came from (if known) or produce a 'delegation error'.

For example, here we write a IM pixel enumeration to the screen using a "-" to output the result to the standard output.

  convert tree.gif  -resize 1x3\!  txt:-
[IM Text]

Or if we like to pass the image, on to another command such as "identify" though a shell 'pipeline', without saving it to a temporary file.

  convert tree.gif -resize 200% miff:- | identify -
[IM Text]

In this case you can also see that the special "-" filename is also used to denote reading an image from standard input by the "identify" command.

Filename Percent Escapes

The save filename can contain a few special percent escape (%) sequences. Specifically, '%d', '%x', and '%o'. These inserts the images 'scene number' into the file name using the C 'printf()' formats. For more information see Writing a Multi-Image Sequence below.

Of course this means that if you want to insert a percent character into the filename you will need to double it ('%%').

As of IM v6.4.8-4 you can now also insert special pre-prepared labels that have been assigned to images, as part of the save filename. For example...

  convert rose: -set filename:mysize "%wx%h" 'rose_%[filename:mysize].png'
[IM Text]
Which saves the built-in rose image into a file containing that images size in pixels. Specifically, the filename "rose_70x46.gif".

Note that only a 'filename:label' can be used within the output filename, though this may change in the future. If that label is not found the '%' is used as is.

Automatic GZip Suffix

IM will also automatically "gzip" images if a ".gz" suffix is given.

For example here I save the built-in "rose:" image as a "gzip"ed, uncompressed GIF file. I turn off the normal LZW compression of GIF, as it would prevent "gzip" compression from achieving its best compression.

  convert rose: -compress none  rose.gif.gz
[IM Output]
How browsers handle a gzipped image depends on the file type returned by the web server and how your browser handled compressed images. Because of this I did not directly display the above image. Click on the 'art' icon to see what your browser does, with such an image from this web server.

Compare the size of this to a normal saved LZW compressed GIF image...

  convert rose: rose.gif
[IM Output]

The "gzip"ed rose is [IM Text] bytes in size, while a normal LZW compressed rose is [IM Text] bytes. As you can see ZIP compression is actually better than the LZW compression the GIF format uses, so may be better for archiving purposes.

Saved Attributes

Under Construction

Other Settings specific to image writing....
    -depth  -quality  -compress -type  -loop
    -set label   -set comment
Also see Image Depth,
Image Type,
JPEG Quality,
PNG Quality.
GIF loop.

Talk about file compressions, which are part of various image formats.

Different compressions are used for different image formats.

Especially the JPEG to TIFF compression change needed.

Using or "-compress
None" and "-compress" NetPBM text/binary format selection.

The GIF compression and the copyright patent.

Other than using IM to reduce -quality or changing the format to something
else the -compression option is rarely used.  Often it is only used internally
by IM to save images using the same compression the image was read with.

Encrypted Images

IM also allows you save sensitive images with encrypted with a pass phrase using the options "-encipher" and "-decipher". See Encrypting Images

Reading Images

It may look weird to talk about image reading after image saving, but reading images is a much more complex matter than saving, with more options and settings being applied to the image as it is being read.

IM by default will attempt to determine the image format type by the 'magic' file identification codes within the file itself. If this fails however you will need to specify the images file format using with the files suffix, or by adding a prefix format.

Some formats will not read any files and ignore any given filename. These are some of the common built-in images...

  logo:      granite:     rose:

Some of them will generate images based on arguments given as a filename and perhaps an extra "-size" controlling the final image size...

  -size 30x30  xc:red
  -size 30x30  gradient:yellow-limegreen
  -size 30x30  pattern:fishscales

In some cases you can even use a format inside the filename argument of another format...

  -size 30x30  tile:pattern:gray95

When a prefix file format is given, any suffix given as part of the filename does not have any bearing on the way the file is read. This is in fact vital when reading some file formats such as the "text:" verses the "txt:" file format handling. Of course if a image generator actually reads in a image file to process it in a special way (for example "tile:") then the suffix (or prefix) file formats will again become important, as it was in the last example.

If the filename is the special string '-' IM reads the image from standard input.

Filename can have the special 'file meta-characters', such as '*' and '?' embedded in them. IM will expand these characters to generate a list of filenames to be read in, avoiding the need for an external shell to do this, or problems with command line length limits. For example...

  montage  '*.jpg' -geometry 50x50+2+2  image_index.gif
will produce a single montage index image of all the JPEG files in the current directory. Note however that I needed to quote the argument to prevent my UNIX shell from expanding the file names rather than ImageMagick. See below for a more complete "montage" specification.

IM can also use a image that is published on the 'world wide web' by specifying that images URL. You can of course also modify that image before finally saving the result to disk.

  convert \
          -resize 100x100 castle_logo.png
[IM Output]

The special character '@' at the start of a filename, means replace the filename, with contents of the given file (with '-' meaning standard input) that is read a file containing a list of files!

  echo "rose:  tree.gif" |\
    convert @-  -frame 5x5+2+2 +append file_list.gif
[IM Output]

Read Modifiers

On the end of the filename and format specification you can also add a special square bracket '[...]' modifier to the end of the filename. These are performed after the whole specified image has been read into memory, but before it is added to the current image sequence.

They are generally used to limit the amount of memory needed, by pre-processing images before all the input images are read in.

Here are the special '[...]' modifiers and their effects. The '#' represent some number.
'[#]' '[#-#]' '[#,#,#]' [#,#-#,#]'.
Will select specific sub-frames from a multi-image file format from the image that has been read in. The given number '#' index specifies the frame number to read. Multiple indexes can be specified in either comma order or as a index range.

The image index start at zero for the first image, 1 for the second and so on. If you specify a negative index then the count is from the end of the image sequence, in reverse order, -1 for the last image, -2 for the second last image.

This is exactly the same convention as used for the Image Sequence Operations.

For example

  convert document.pdf'[0]'     first_page_of_pdf.gif
  convert animation.gif'[1-3]'  second_to_fourth_frames.gif
  convert animation.gif'[-1,2]' last_then_the_third_frame.gif

From IM version 6.2.6-2 a new modifier was added to help IM users to handle very very large images.

This modifier will resize the image that was just read in, immediately before that image is added to the other images already in memory. For example a small image can be enlarged as part of the image read.

  convert pattern:gray95'[60x60]' enlarged_dots.gif
[IM Output]

The modifier is most important when you are attempting to read in lots of very very large images, as each image will be resized before the next image is read, producing a substantial saving in total memory needed to handle those images.

For example instead of...

  montage '*.tiff'  -geometry 100x100+5+5 -frame 4  index.jpg
which reads all the tiff files in first, then resizes them. You can instead do...

  montage '*.tiff[100x100]'  -geometry 100x100+5+5 -frame 4  index.jpg

This will read each image in, and resizes it, before proceeding to the next image. Resulting in far less memory usage, and possibly prevent disk swapping (thrashing), when memory limits are reached.

For JPEG images I recommend you use something like...

  montage -size 200x200 '*.jpg[100x100]' -strip \
          -geometry 100x100+5+5 -frame 4  index.png

Note that the "-size" setting has a special meaning for JPEG image format reading. It is passed to the JPEG library and limits the reading in the JPEG image produce an image that size or slightly larger. In other words it further limits the memory usage for large JPEG images, before the input modifier resizes the image down to the actual size wanted. See Reading JPEG Images.

Only the JPEG image file format uses "-size" in this way. You can not use it for TIFF or PNG image file formats, which is why the input resize modifier was developed for general use.

From IM v6.3.1 if you also add a offset the above becomes a crop of the image being read in.

For example, To get a smaller 600x400 pixel tile from a very large image.

  convert 'image.png[600x400+1900+2900]' tileimage.png

This however will read in the entire image into memory then crop it before it is finally added to the current image sequence.

If you want to handle really large images I suggest you look at the "stream" command and pipe you image into the "convert" command for further processing. See Massive Image Handling below.

Note however that '[]' characters are usually also special shell meta-characters, so if you use them it is a good idea to quote the additional modifier, to stop UNIX shells interpreting it.

Also when you use a modifier, you must let IM handle any special file expansion meta-characters, such as '*' and '?', as a UNIX shell will not 'find' the requested files due to the modifier. What it actually does in that case is shell dependant. As such the whole filename should be quoted when using read modifiers.

You can also get IM to read images based on a list of numbers. For example..

 convert 'image_%03d.png[5-7]' ...

will read in the filenames  "image_005.png", "image_006.png", 'image_007.png"...

You will need to quote the filename so as to prevent the shell from
interpreting the special '[..]' characters.

If the image is "gzip"ed, IM will automatically uncompress it, into a temporary file before attempting to figure out the image format and decode the image file format. As such you can not only save images in gzip compressed format, but use them directly in later IM processing. For large text based images this can result in enormous disk space savings.

The PNG format includes "gzip" compression as part of its format specification. In this case the first digit of the two digit PNG "-quality" setting defines the level of compression. For more detail see PNG Image File Format examples.

The above is only a short summary of the special input options available when reading images into ImageMagick. A full summary is given on the The Anatomy of the Command Line page on the ImageMagick Website.

As shown previously the image input can be modified by some IM settings such as "-size" for image creation and JPEG reading. Other options also effect image input creation, including, "-page", "-type", "-dispose", "-delay".

WARNING: Be very careful when passing a user provided argument to IM in a script, insuring that the argument is what you expect. You do not want to let a web image processing script return a image of the system password file for example.

Compressing Images

Under Construction

IM will also read these compressed files via the appropriate commands.

After that you can refer to the image in the browser as most web servers and
browsers will support sending the compressed file, compressed and uncompress
it for use at the other end.

Compressed XPixmap (xpm) images is also automatically handled by the Xpixmap
library, so you can use that format directly in many X window programs.

FUTURE: See Image Attributes, in IM basics.

Importing Images from special sources

To grab an image X windows Display, using the "import"..
import     read images from the on screen display

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

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

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

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

You can also import images by reading from "x:" or a special window selected by ID using "x:{id}". If you write to "x:" you will display an image on script using a very low level "display"-like way.

Windows Clipboard  use the "clipboard:"  read delegate, for example...
        convert clipboard:myimage image.png

Special File Formats (specific to IM)

As you saw above, ImageMagick understands a huge number of well known image file formats. It also includes a good number of special image generators. On top of these there are also some very special file formats specific to IM, which allow some very special handling of images.

All these special file formats are both read as well as write formats.

is the ImageMagick File Format. The whole image sequence and all the attributes associated with the images are saved in this file format. Of course only ImageMagick commands will read this format, so it is not suitable for long term or transferring between different image processing packages.

The "miff:" file formats primary purpose is as a intermediate save format during large image processing scripts. Or when 'pipelining' an image from one IM command to another. See the last example for one such pipeline.

For those interested in parsing this format, it is a semi-text format consisting of a ascii header of image attributes, a line containing a single formfeed, followed by the raw image data as a binary. This header is itself a useful way of extracting basic image information in various image processing processing scripts.

For example here are I use a GNU-sed command to show all the attributes (the few that there are), of the built-in "rose:" image.

  convert rose:   miff:-  | sed -n '1,/^\f$/{ /^\f$/d; p; }'
[IM Text]

This is actually quite useful as it reveals all the current settings flags and meta data that IM knows about the image. However there is also statistics, as these are generated by either the "identify" command, the "-identify" operator or the special "info:" format; if requested with a "-verbose" option. (see next)

The "miff:" format can also handle multiple images, and in fact does so simply by appending the images together.

This means you do not need to process all the images, by a single command. You can put the command in a loop, and just output MIFF format images, one after the other, to the loops standard output. That result can then be piped directly into a single command to generate montages, collages, animations, or something else.

For example the following generates a list of colors starting with the letter 'b', then uses a separate convert command to generate label for each color, one label at a time. These are then montaged together to produce a simple color table.

  convert -list color | egrep '^b' | \
    while read color junk; do \
       convert -label $color -size 70x20 xc:$color  miff:-; \
    done |\
      montage - -frame 5 -tile 6x -geometry +2+2 \
              -background none color_table.png
[IM Text]

The above was also converted into a script "show_colors" which you can use to search for and find colors to use in your image.

This looped image output technique also means you can use code like "-write miff:-", to output a miff format image from multiple places in a single command. Each image will be automatically append together in the final output stream.

This stream can not only be feed into "montage", say to debug image processing, but also into "display" (with some timing settings) as a simple slide show. Finally this format (while not compressed) can handle ANY type image IM knows about at any depth or quality level the IM was compiled with.

It is about the most ideal format to use for temporary images, and pipelined image commands you can use, though IM is the only one that can read it.

A very useful image file format, indeed.

The "info:" file format (added in IM v6.2.4) does NOT output an actual image! This format basically outputs the same information that the ImageMagick "identify" command will output.

Like "identify" this output format is controlled by the "-format" and "-verbose" options allowing you to output just the specific information you are interested in, as defined by the Image Property Escapes page.

For example instead of piping a MIFF image to "identify" as we did above (see Saving Images), we could have used the following, to retrieve the single line identification of the resulting image format.

  convert  granite:  info:-
[IM Text]

Of course you can use a "-format" setting to output the desired information in a specific and more parsable way.

What is so useful about "info:" is that you can now produce your image, while extracting extra information about it, at the same time. This is done by using the "-write" operator to save this special image format to a file (or the commands normal standard output).

  convert rose: -shave 12x0 -repage 64x64+9+9 \
          -format '%wx%h %g'  -write info:info_paged.txt    paged.gif
[IM Output]
[IM Text]

There is also a "-identify" operator that is equivalent using "-write info:" to output image identification information to standard output, or "-print" output operator. This make it even easier to monitor what is happening to your images when debugging your IM commands.

For example...

  convert logo:    -identify    -trim             -identify \
          +repage  -identify    -resize 80x80\!   -identify \
[IM Output]
[IM Text]

Here you can see how "-trim" reduced the size of the image but preserves the 'crop' information of what part of the image was trimmed, then the "+repage" removing that extra 'canvas' or 'page' information.

Also like the "identify" command, both "info: and "-identify", will become much more verbose, if the "-verbose" setting is turned on. Here I limit the long output to just the first few lines, just so you can get a bit of an idea about it.

  convert  rose:  -verbose  info:-  | head
[IM Text]

The "-verbose" setting will also cause extra information about images being read in or out, to be printed to the standard error (with the exception of the "info:" format). It also causes some operators like "-colors" to output additional information. As such you may like to turn it off again after using it with either "-identify" or the "info:" format.

For example   
"-verbose -write info:image_info.txt +verbose"    or    "-verbose -identify +verbose" .

Scripted readers of any form of "identify" command output, should do so in a case in-sensitive way, for backward compatibility between different versions of ImageMagick.

NOTE: "info:" (and "-identify") is only special an output format, producing the same output as the "identify" command. You can not read, or create an image using the "info:" file format.

As an output format, this will just 'junk' the image results. As such if used as the final argument in a "convert", "montage", or "composite" command the final result will not be saved!

Why? Well it may be that you are more interested in specific images, generated during image processing rather than the overall result, especially when debugging.

For example, here we extract and save one image, from an image sequence, then junk all the other images using "null:".

  convert  eye.gif news.gif storm.gif tree.gif rose: logo: cyclops.gif  \
            \( -clone 2 -write write_storm.gif \)   null:
[IM Output]

This is a lot simpler than attempting to delete all the other images one at a time.

As a input image format however, "null:" will generate a special placeholder image of a single transparent pixel, with with a special 'null source' flag, in the current image sequence.

This special image is especially important to Leave Gaps in a Montage, and as a list separator for multi-image Layer Composition. It is closely related to another special image format known as a 'missed image', that can be generated for operations like "-crop". This image format is produced when an operation produces an empty or non-sensible result. Both images are a single transparent pixel, and as such "null:" images will also be treated as if it is a 'missed image'.

At this time there is no method to remove any "null:" or even 'missed image', from the current image sequence. However such a method has been proposed. Mail me if you find you need such a method.

This is a simple ASCII text file, which basically lists each pixel in the image, one per line. It is not a general text to image converter, for that see Multi-line Text Files Examples.

For example here is a "netscape:" image scale to a 2x2 pixel image, then listed using a "txt:" image format.

  convert  netscape: -scale 2x2\! txt_netscape.txt
[IM Text]

The first line (header) of the image is packed with the basic information about the image. The information consists of...

File Magic: The image header defines this file as a the special IM text image format (EG a "ImageMagick pixel enumeration" file), this is known in computing circles as the files 'magic' or the code string which identifies this file as being this specific file format.

Image Size: The next two numbers define the size of the image contained in this file. Multiplying these numbers together will also tell you how many lines should follow the header to fully define the image.

MaxValue: The last number in the header defines the 'maximum value' of the image data that is possible. In the above examples this was '255' which is a result of using a 8 bit depth.

The reason it output the built-in "rose:" image at this depth is because it was defined internally using 8-bit values, and as such IM preserved this depth level for the image. See the section on the depth setting for more information.

But you can override the depth setting (up to the limit of your IM's Q or Compile-time Quality setting, by changing the images "-depth". For example here I output the color values as 16 bit (or values from 0 to 65535)...

  convert -depth 16 netscape: -scale 2x2\! txt_netscape_16.txt
[IM Text]

At this time you can not set a specific 'Maximum Value' to use in the output file format. You can only define a different value in terms of the current "-depth" setting, making the maximum value equal to 2^depth-1.

Colorspace: The last item in the header defines the colorspace of the image being output. If the image contained any transparency, a final letter 'a' (for alpha) is also appended to the colorspace name, and an extra column of numbers added between parenthesis. Grayscale images will use the 'rgb' format, though all three numbers are the same value.

For example here is the same image using a colorspace of 'LAB' with an alpha channel added!

  convert  netscape: -scale 2x2\! -colorspace LAB -matte txt_cspace_lab.txt
[IM Text]

After the initial header are the Pixel Data lines, one per pixel in the image.

Coordinates: The first two numbers up to the colon ':' is the pixel position, starting from 0.

Color Values: After this the color values for the pixel (from 0 to the MaxValue given in the header) is given in parenthesis, with anywhere from 3 to 5 numbers depending on the current colorspace for the image. Spaces are optional so caution is advised when parsing the numbers in parenthesis.

Color Comments: Anything that follows the numbers in parenthesis is regarded as comment. IM will fill in extra information on the pixel color using formats that it can parse as a color argument (See "-fill" manual entry for details of these color specifications).

The color comments are however variable, and may output RGB() or color names depending of the pixel data given. Also exactly what color comment is provided is highly dependant on the IM version you are using, especially in early IM v6 versions and before. There is no guarantee that this comment area will not change again in the future, so it is best not to rely on it. IM doesn't.

Here is an example of correctly reading a Pixel Enumeration in a shell script. The exact format of the TXT image is defined by the convert command, then 'tail' is used to junk the header, 'tr' to character replace every non-number character with a single space, so that the later 'while' can read it easily, junking any comment numbers that may have been left.

  convert  rose: -resize 3x2\! -depth 8 -colorspace RGB +matte txt:- |
    tail -n +2 | tr -cs '0-9\n'  ' ' |
      while read x y r g b junk; do
        echo "$x,$y = rgb($r,$g,$b)"
[IM Text]

Reading TXT images is also valid. You do not need to define ALL the pixels in the image. In fact you do not even need to have the pixels in the correct order. ImageMagick will just read each of the pixel in turn and 'draw' it onto a blank image canvas. Only the numbers in the parenthesis on each line is used for this.

The initial blank canvas, is normally cleared as set to the current background color. As such any pixel not provided by a "txt:" image, will be left as this color.

The "txt:" format is especially useful with the "-unique-colors" operator, which replaces each image in the current image sequence with a new image containing one pixel for each unique color found. When this is output to a "txt:" format file, you get a basic summary of the colors contained in an image (though not their counts, or histogram).

For example here are the colors used by the tree image. As GIF can only use 8 bit numbers, I also chose to output the file the same "-depth".

  convert tree.gif -unique-colors -depth 8 txt:-
[IM Output]
[IM Text]

There is another alternative to using the IM "txt:" format using the various NetPBM image file formats. IM by default outputs this format as binary, but you can turn off "-compress" to output a ASCII text version of the NetPBM format. For example.

    convert tree.gif -unique-colors -compress None -depth 8 tree_netpbm.ppm
[IM Text]

You may notice that the numbers in the above matches the number in the IM's Enumerated Pixel ("txt:") format. See Resized Gradient for some examples of generating a NetPBM format image for IM to read.

If you just want the color of a specific pixel you can crop the image down to one pixel, and output it as a "txt:" image.

  convert rose: -crop 1x1+12+26 txt:
[IM Text]

Or you can use a special FX Escape Format to output the color in a form directly usable by IM.

  convert rose: -format '%[pixel:u.p{12,26}]' info:
[IM Text]

See also Extracting Image Colors.

This is actually the "miff:" image format, but with a very large image comment that contains a complete count of all the colors within the image. That is in the "miff:" text header 'Comment={...}' attribute.

For example, here we again list the colors present in the "tree" image, but this time including the pixel count for each color. The text histogram comment is extracted from the "histogram:" image using a secondary "info:" formatted identify.

  convert  tree.gif  -format %c histogram:info:-
[IM Output]
[IM Text]

The "info:" output format was added to IM v6.2.4. For IM versions before this use..

  convert  tree.gif histogram:- | identify -format %c -

You will note that the format is almost exactly the same as that of the previous TXT, or IM Pixel Enumeration Image format, including the comments on the color values. The only difference is that the X,Y location has been replaced by a count of the number of pixels.

The image itself is a histogram graph, 256x200 pixels in size. The x-axis is color value (0-255) and the y-axis is pixel count (normalized to the number of pixels). The histogram for each channel is displayed in the color it represents, and added together. Thus, red and blue overlap to make magenta. In other words with color channel has its own separate histogram.

If you want the image converted to some other format, just save it into that format. "histogram:" is a special image processing format. It will convert the image, then output in the format specified by the filename suffix or further "format:" codes.

  convert rose: histogram:histogram.gif
[IM Output]

An image that is very dark will be heavily weighted to the left, while a light image will be heavily weighted to the right. Mid-tones, likewise, are represented in the middle.

To see this better here I separate the histograms for each of the color channels. I also strip the histogram text comment, and resize the image for display.

  convert histogram.gif -strip -resize 50% -separate  histogram-%d.gif
[IM Output]
[IM Output]
[IM Output]

For the "rose:" image above you will see that red is spread more showing its vital importance in the image. On the other hand green and blue spikes on the left, showing that is has very little influence on the image at all.

If you are more interesting in the brightness of an image rather than its colors (more typical), convert the image to a gray-scale before generating a "histogram:" image. image generated by 50%.

  convert rose: -colorspace Gray \
[IM Output]

As you can see the histogram of a gray-scale image is a little different. As the predominate red color become more of a mid-tone grey color, producing a spike in the center of the histogram. Also the small area of off-white in the image now produces a distinct spike at the extreme right of the graph.

The completely empty space at the extreme left also shows that there are no dark patches in the image at all.

Unfortunately as "histogram:" is an output format, you will either need to 'pipe' the image into another command, save it to disk, or use the special "mpr:" save/read, if you want to process the image further. See example in "mpr:" below.

The actual 'histogram' data used to generate the above images (rather than the actual color count data used) is currently not available from the command line.

(memory program register) will save the image into memory, rather and onto disk. As such if you want to save an image for use latter, in a complex image operation you can do so.

Of course as you are saving into memory, you will need to do this as a Write operation, and not when the command is about to exit, and the commands memory is returned back to the system.

The 'label' given to "mpr:" can be anything you like, it is only a label on where the image was saved in memory. It can even be just numbers for people who do scripting and don't want to deal with names.

After you have saved an image see below), you can then read in the image again, from the same 'labelled' memory location, as many times as you like. For example...

  convert tree.gif -write mpr:tree  +delete \
          mpr:tree  mpr:tree  mpr:tree   +append  mpr.gif
[IM Output]

In many ways this is like using Clone but by taking the image completely out of the current image sequence.

The best feature of this method is that it also allows the use settings and operations that only work on image input. For example, using it with the input image "tile:" operator to tile an image over a larger area.

  convert tree.gif -flip   -write mpr:tree  +delete \
          -size 64x64 tile:mpr:tree   mpr_tile.gif
[IM Output]

You can also use "mpr:" to grab the output of some of the special output image format filters for further processing. For example here we grab the output image from "histogram:" and continue to process it to make a smaller histogram chart, before actually writing it to a file for real.

  convert rose: -write histogram:mpr:hgram  +delete \
          mpr:hgram  -strip  -resize 25%    histogram_resized.gif
[IM Output]

The "mpr:" in-memory save is actually the only way you can re-use images already in-memory through special I/O filters such as "histogram:" or See "tile:".

The same is true for the special options that take an image, such as "-tile" or for "Color Mapping" images using another image as a source. See Multi-image Color Maps

It is also the only way to use the -draw 'image' method to overlay images using a generated in-memory image, though there are lots of other better methods to do this.

Note that "mpr:" image actually saves the whole image sequence and not just one image. It is a bit like taking a snapshot of the current image sequence so you can reload it later on for further processing. This for example allow you to take copies of a whole animation sequence, for duplicating or cloning, without needing to know how many images are actually involved. See Layers Composition for an example of doing this.

The Image Cloning operator cannot generally handle a unknown variable number of images, and in fact before the Clone operator was added "mpr:" was the only method available for duplicating in-memory images, without using intermediate disk files.

Is a special IM specific save format that is designed with really large images in mind. Basically is is a memory-mapped disk file of program memory, that is saved to disk as two binary files, a ".mpc" holding the images meta-data, and a ".cache" holding the images pixel-cache.

The "MPC:" format saves two images.

For example...

  convert very_big_image.tif  very_big_image.mpc
will create two files on disk. A small "very_big_image.mpc" file and a special memory dump file called "very_big_image.cache". The second file size will likely be larger that any other image file format, and will only be usable on machines with the exact same hardware and operating system version, as what it was created on.

However the file does not need to be 'read in' or 'decoded' but can be directly 'paged' into computer memory and used exactly as-is, without any processing overhead, only lots of disk space. In other words it has a next to instant in reading time, though disk speed access time. No decoding needed.

Because the image is 'memory-ready' it is especially useful for temporary images of all sizes as it will be usable immediately by the next IM command you issue. But remember two files are generated and they will be larger than a normal image filesize, so be careful of your disk usage.

My own IM scripts do this. For example see the scripts "de-pixelate", and "divide_vert", which make use of quite a few temporary image files for image processing operations.

This can be extremely useful for scripts or Mogrify Alpha Compositing that needs to be able to read the same image, over and over and over again, as IM does not have decode the image, or use up lots of memory just to store it.

This is also very useful for processing a very large MPC copy of the image, where you must extract or crop a smaller section of the image for the for actual processing. However as most image operations actually make clone copies of images during processing, a new in-memory copy could be made. So some care is still needed.

For more information see Really Massive Image Handling below.

This is a special image display output format, which will directly display the image result to your screen. Instead of saving the image into a file, it just displays the result.

This is very useful for quick testing IM commands to see what the results will be, and is highly recommended for this purpose. However they are only very simple versions of the "display" and "animate" command.

For example, get a fast summary of images in a directory...

  montage *.jpg x:

See the areas that are different between two images...

  compare image1.png image2.png x:

Note however that neither display methods understand the use of semi-transparency. As such any semi-transparent pixels are displayed fully-opaque. Because of this the following does not display the resulting image very well.

    convert rose: -matte -background none -vignette 0x3 x:

The "display" command solves this by overlaying the resulting image onto a checkerboard background, allowing you to see the semi-transparent pixels properly...

  convert rose: -matte -background none -vignette 0x3 \
          miff:- | display -texture xc:black -

To simply the use of "display" for displaying the results, the special 'show:' or 'win:' output Spawning Delegate will do the same thing, and even automatically background the display when IM finishes.

  convert rose: -matte -background none -vignette 0x3   show:

Unfortunately none of these methods will display animations very well.

Reading X Display

You can also read the display using the "x:" operator, in much the same way as you can with the "import command. In fact without options it acts exactly like that command. Use the left button to select the window to grab and 'import', or mark out an area using the middle button.

However by providing a window name you can grab a specific window. For example this will grab the window titled 'MailEd'

  convert x:'MailEd'  window.jpg

I can even grab and immediately display that grabbed window.

  convert x:'MailEd'  x:

To grab the whole display use 'root' for the window name.

  convert x:'root'  full_screen.jpg

Or use the Read Modifiers to grab a specific area of the display.

  convert x:'root[300x400+879+122]'  part_screen.jpg

Read and Delete this image file.

This is a special image reading file format which will cause IM to delete the given image file after that file has been read into memory.

This is very dangerous and should be used with extreme caution.

It is used for example in Delegate Spawning. Here the backgrounded delegate program read its input image then deletes it to notify the foreground process, that it is ready to become independent, allowing the foreground command to cleanup and exit.

  Inline images let you define the image in base64 encoding directly.
  This is more typically used as part of API's as an alternative to 'blobs'.
  they have a look similar to (but much longer)

  If the inline image exceeds 5000 characters, it must be referenced from a
  file instead inline:inline.txt

Delegates and Coders for Image Formats

Coders are dynamic library modules (usually written in the C programming language) that handle the "format:" aspect of image input and output. They can also be used by users to create special purpose filters. They may require the installation of extra external libraries to be installed, which are often called 'delegate libraries'.

The other type of 'Delegate' is to tell IM about other external commands that IM could use to decode some image format it has no built-in 'coder' for. The most well known 'delegate' program is "ghostscript" which will allow IM to read, and convert Postscript and PDF pages to a raster image.

However 'delegate commands' are very useful for users too, as it allows you to modify how IM handles special types of images, or to provide alternative methods to read and write those images.

The 'commands' themselves are listed in a file named "delegates.xml", and which is located in IM's system configuration directory. But it will also read a "delegates.xml" locating in the users personal ".magick" sub-directory of there Linux/UNIX home directory. And it is in this second file that users should place there 'command delegates'.

Input Delegate Command Example

For example I can create a personal "delegates.xml" file in the ".magick" sub-directory of my Linux/UNIX home directory, of the form...

<?xml version="1.0" encoding="UTF-8"?>
  <delegate decode="flip" command="convert '%i' -flip 'miff:%o'"/>
This is a complete 'delegate' configuration file, but only the middle line is an actual delegate. A very simple one that tells IM that if it sees an image with either a '.flip' suffix or a 'flip:' format prefix, it should call the above command, to read the 'flip' format image.

For example..

  convert flip:tree.gif   delegate_tree_flip.gif
[IM Output]

In this case all the delegate command does is use a separate IM "convert" command to 'flip' the image upside down, before the original IM command even reads and processes the image!

The delegate assumes the command will understand the image file format given and that it will return ANY image file format that IM itself will understand (the MIFF image file format in this case).

The '%i' and the '%o' parts of the delegate represent temporary filenames the command is to read a copy of the input image and where IM expects the command to write its 'converted' output. These filename are generated by IM, and will be located in a temporary directory. These temporary filename do NOT have any image suffixes, so it is important that you prefix the image format type if necessary.

It is done this way for security, and because IM itself may only be reading a stream of data, and not an actual file. It also means the secondary command does not have to deal with such matters.

There are other '%' substitutions for things like secondary temporary filenames for intermediate temporary files, and for many other purposes. More detail about these escapes and other delegate options are provided in the comments at the top of the IM installed 'system' "delegate.xml" file.

Now this may seem like a rather silly and trivial example, but it basically means you can now use a secondary command to convert ANY data file into ANY image IM understands. IM will then know how to handle that data type automatically given the image suffix, or a format prefix, without you needing to remember all the details.

Lots of delegates of this type has already been added to the system file, so it is worth a look.

For security reasons delegates in a personal "delegates.xml" file will not override the delegates defined in the system installed "delegates.xml" file. You can only add new unique delegate formats in ".magick/delegates.xml" in your home directory, later duplicate delegates will be ignored.

Of course if the input format is already known internally then of course system delegates are not looked at.

Also as always, sanitise any user (especially web user) input, as you don't want the user to make use of a delegate without you knowing about it.

For example as of IM v6.4.2-6, a "autotrace:' delegate was added to the system delegates file, which will run the "AutoTrace" command while reading ANY input image. IM converts the input image to the required PNG image format, filters it though the delegate, then reads and converted the resulting SVG, to generate a smooth edged version of the original input bitmap image. See Raster to Vector Converter Example If you want to use a converter that may generate multiple image files (such a PNG), you will need to merge all those separate images into a single multi-image format such as MIFF, so that IM can read the multiple images from the one output file.

Sometimes IM will string together multiple delegate programs to read in an image. For example to read a 'HTML' page as an image, it first calls the delegate "html2ps" to convert it to postscript. Then it converts the generated postscript file into a set of multiple images using the special "ghostscript" program delegate.

Of course using two delegates like this can produce other problems due to the complex interactions and bugs that may be present. But in general it works.

Output Delegate Example

Similar things are done when saving to specific image file formats that IM does not directly understand.

For example by adding this delegate to your personal ".magick/delegates.xml" file, you can tell IM how to create a '.xyzzy' image file.

  <delegate decode="gif" encode="xyzzy" command='mv "%i" "%o"'/>
Of course this just quickly copies a GIF file format image as a TMP file format, but the command can be any type of image converter, script or shell command sequence you like.

With that personal delegate, IM can now create your '.xyzzy' images, having been provided at least one method of going so.

  convert rose:  -negate   rose.xyzzy
  identify rose.xyzzy
[IM Output]

Note that the identify in the above does not understand the '.xyzzy' suffix (no input delegate has been provided). However the file 'magic' tells IM that it is in reality a GIF image format, so IM handles it correctly anyway, without needing a special input delegate or coder.

This is the 'MAGIC' part of 'ImageMagick'.

Spawning External Commands

A external command delegates does not have to just be for converting images to/from files, but can be used as a quick way to run (or 'spawn') complex command in the background. Such a delegate will have the attribute "spawn="True"" added to it, and will launch the command, wait for it to delete its input image, then continue as normal, leaving the command running in the background.

For example two output delegates "show" and "win" both provide a simple way to display the result of a command in the IM "display" program.

For example..

  convert rose: label:rose -append   show:

Will append a label to the built-in 'rose' image and just display it on the screen. When the spawning delegate has read its input image (typically using the special tmp:" input format (see above), the main foreground process will exit, leaving the 'display' program running in the background, showing the results.

This is a lot more convenient that trying to remember all the special options that a scripted "display" command needs. Or for your own complex command that you run with IM's results.

I recommend you look at the "show" spawning delegate in you system "delegate.xml" file.

Delegate Listings

A full list of external delegates that IM can use for converting image formats is read from a special system file called "delegates.xml" as well as a personal "delegates.xml" file (see below). If you can find this file it makes interesting reading.

The format of this file however is too complex to do into here, though it is explained in both the system file and the manuals provided both online and with your ImageMagick installation (docs area).

A simplified summary of the delegates and conversions that IM is reading from these files can be printed using...

  convert -list delegate

Note that some delegates declared in any "delegates.xml" file will not be listed if it is marked as a special internal delegate using a 'stealth="True"' option in the delegate entry.

All delegates are optional, and more than one can be created for a specific conversion. If one delegate is not available (it errors or image is not created), then IM will try the next delegate, until one is found that does work, or it runs out of delegates to try, at which point an error will be produced indicating it can not read that image.

Postscript and PDF Delegate

By using delegates ImageMagick can make use of external programs to do some of the more complex and specialised image format conversions.

For example, while Postscript (PS:), and Encapsulated Postscript (EPS:) can be written directly by ImageMagick. These file formats can not be read by IM. Postscript is a full computer language and requires a very complex interpreter to create images from it. As such it is far beyond the scope of IM to handle the reading of this file format.

To solve this IM looks for a external delegate program called "ghostscript" to do the work of converting an PS or EPS format file to some other image format that IM can read easily.

Of course that means that if you get an error like...
convert: no decode delegate for this image format `...'
Basically means that IM was unable to find the appropriate external program to convert your given image format into an image format that IM itself can handle. For Postscript images, that usually means "ghostscript" is not installed, mis-configured, or in an unknown location on your system.

The PDF/PS "ghostscript" delegates are in a special format used internally. IM internally examines postscript format images to attempt to determine exactly how to rasterize the file via the given delegates.

In fact, multiple PS delegates are present and selected by IM depending on the situation. For example the ghostscript device used ('bmpsep8' verses 'pngalpha') is selected depending on if "-colorspace RGB" had previously been set or not.

For PDF we use the 'ps:color' delegate rather than 'ps:alpha' because the 'pngalpha' ghostscript device only supports a one-to-one page-to-image conversion and PDF's generally are multi-page.

Direct Delegate Format Conversion

The delegate system also allows IM to call a external program to convert a image from one format to another format without processing the image itself.

For example if you try convert a 'Adobe Illustrator' file (".ai") (which is a type of Postscript), to EPS (encapsulated postscript)...

  convert -density 300  map.eps

Then IM will first read the image into memory, and then find that it does not actually modify it.

Because no change was made to the image, and a direct delegate conversion is available, it will call the special "ghostscript" utility "ps2eps" to do the conversion directly. The result however is that the generated EPS is a vector postscript image, rather than a postscript wrapped raster (pixel array) image at the density requested.

You can however force IM to actually read-in and write-out the image, as a raster, by using the special "-taint" operator to mark it as being modified, without actually modifying it. As such this will force IM to output a rasterized image data, in the encapsulated postscript file.

  convert -density 300  -taint  map.eps

Other Delegate Examples

Modifying Postscript Delegate for CMYK postscript

See Blog of John for details.

DCRaw 8-bit processed camera image Delegate

A alternative delegate for reading 8-bit fully processed 'raw' digital camera images (CRW, CR2, NEF, etc) is...

  <delegate decode="dcraw8" command='dcraw -v -w -O "%o" "%i"'/>
This will read the 'raw' camera image, and convert it to a PNG file format (though you can also just as easily add a '-T' flag and use a TIFF image format). That output image turn is readable by ImageMagick.

By adding this delegate can then use it simply, for any ImageMagick image read operation (any API, not just command line), and IM will handle all the file IO and cleanup. For example...

  convert dcraw8:image.crw  image.png

If you do not define the filepath of the "dcraw" executable, IM will search the for the program along the users current PATH environment variable, however allowing this could represent a security problem. System installed delegates generally define the command path fully.

Video decoder delegate using 'ffmpeg'

For example here is a delegate published by Mikko Koppanen, on his Mikko’s blog site. Add this to your personal "delegates.xml" file in ".imagick" directory of your home...

  <delegate decode="ffmpeg" command="'ffmpeg' -i '%i' -y -vcodec png -ss %s -vframes 1 -an -f rawvideo '%o'" />
IM can now use the "ffmpeg" program to decode the frames from an MPEG video image. For example.

  convert  "ffmpeg:test1.mpg[40]"  frame_40.png

Writing a Multi-Image Sequence

A major problem with saving images, is that ImageMagick works with a ordered sequence (list) of images, not just one image at a time. Because of this IM will attempt to write ALL the images in the current image sequence into the filename given.

If the file format allows multiple images IM will by default save all the images in the current image sequence into that image file. For example if you look at the GIF Animation Basics examples page you will see that it will save multiple image frames into a single image file format to produce a animation.

If the output format does not allow you to save multiple images into the one file, IM will instead generate multiple files. For example, when saving to image formats like JPEG and PNG and so on.

You can also force this behavior on image formats that do allow multiple images per file, such as GIF and PS by using the "+adjoin" output file handling setting.

  convert eye.gif news.gif storm.gif  +adjoin  image.gif
[IM Output] [IM Output] [IM Output]

If you look closely at the filenames of the three images generated above, you will see that IM generated images named "image-0.gif" to "image-2.gif".

Previous to ImageMagick version 6.2.0 the output filename of the above would have been "image.gif.0" to "image.gif.2". This resulted in many problems due to the loss of the filename suffix, so was changed to add the image number, before the filename suffix.

An alternative is to add a 'C language printf()' construct "%d" to the output filename. This special string will be replaced by the current image number of each image in sequence.

  convert eye.gif news.gif storm.gif  +adjoin  image_%d.gif
[IM Output] [IM Output] [IM Output]

Here we generated the images "image_0.gif" to "image_2.gif", using an underscore rather that the IM default of a dash.

Not only can you use '%d' for a decimal number, but you can use '%x' for a hexadecimal number (lowercase), '%X' for a hexadecimal number (uppercase), or '%o' for an octal number.

If you really want a percent character which is followed by one of these letters, then you will need to double the percent character to escape its meaning. That is you will need to use '%%' to ensure you actually generate a percent symbol.

The '%d' in the output filename actually enables the "+adjoin" setting of ImageMagick, automatically.
However while I don't actually need the "+adjoin" in the above, it is probably a good idea to provide it anyway, just so it is clear that you are generating separate images.

This works well for a small number of images, but if you have more than ten images you will get a mix of image with one digit and two digit numbers. And if you have more than a hundred, you get three digit numbers too. When that happens, directory listings will no longer list the saved images in sequence, since "image_15.gif" would alphabetically appear before "image_5.gif".

Of course there are ways to fix this. For example using a command line shell expressions like..

  convert image_[0-9].gif  image_[1-9][0-9].gif  animation.gif
  convert image_?.gif  image_??.gif  image_???.gif  animation.gif
  convert image_(?|??|???|????).gif  animation.gif
  convert 'image_%d.gif[0-123]'  animation.gif

The last method is the proper IM way of handling a sequence of files, though you need to know the range of number you want to use. The '%d' formats each number to match the filename (see next)

In any case, this is awkward and prone to mistakes, can produce errors if files are missing, and can be dependant on what type of computer system you are using. Better to avoid this problem altogether.

If you are familiar with the 'C' language (look up the UNIX system man page for 'printf') then you will probably know that if you use something like "%03d" you will always get 3 digit numbers (with leading zeros) for the image sequence frame number. The image names would in that case be "images_000.gif", "images_001.gif" and so on.

  convert  eye.gif news.gif storm.gif  +adjoin  image_%03d.gif
[IM Output] [IM Output] [IM Output]

Using this method, the images will not only be numbered, but will also list alphabetically correctly, making image file handling a whole lot easier.

I thus recommended you add a '%03d' or whatever is appropriate, to the output filename whenever you plan on writing multiple images, as separate image files.

Written Scene Numbers

If you want the image sequence to start at '1', instead of '0', and don't want to rename all the resultant image files, the simplest solution is to prepend a 'junk' image on the front of the sequence to be written.

  convert  null:  eye.gif news.gif storm.gif  +adjoin  image_%01d_of_3.gif
  rm image_0_of_3.gif
[IM Output] [IM Output] [IM Output]

You can, of course, use "+insert" to do this after your image processing. This is not a particularly nice solution, but works, and is simple, and backward compatible with the older major versions of IM.

As of IM version 6.2 you can use the "-scene" setting to set the starting number for the current image sequence.

  convert  eye.gif news.gif storm.gif  +adjoin -scene 101 image_%03d.gif
[IM Output] [IM Output] [IM Output]

Which produced the image files "image_101.gif" to "image_103.gif".

Writing an Image, Multiple Times

While on the subject of writing images, it is possible to write an image from the middle of a sequence of image operations, using the special "-write" image operator.

This is very useful when you like to output an image multiple times with variations in image processing, such as thumbnail size. It can also be used for grabbing an image for debugging your IM command.

  convert cyclops.gif  -fill lightsteelblue  -draw 'color 0,0 floodfill' \
          \( +clone -resize x128  -write  cyclops_lrg.jpg +delete \) \
          \( +clone -resize x96   -write  cyclops_big.jpg +delete \) \
          \( +clone -resize x64   -write  cyclops_med.jpg +delete \) \
                    -resize x32           cyclops_sml.jpg
[IM Output] [IM Output] [IM Output] [IM Output]

As you can see we can use the Image Sequence Operators to process a 'clone' of an image, write out the result, then delete and backtrack back to the original source image, repeating the process as many times as you need.

In this particular case it means I did not end up resizing the same image over and over, but each time re-started from the source image, and thus preventing the image degrading due to processing it multiple times. It also meant I could have just as easily generate the smaller images first, then the larger images after that, without problems.

Note that "+clone" does not actually duplicate the image data! IM uses a reference-counted cloning process which only copies the image pixels when they are updated. As such only enough memory to hold the original image and the new resized image is actually used, in the above process. It also makes "+clone" very fast.

Really Massive Image Handling

For handling any sort of large image it would probably be better for you to use a Q8 version of ImageMagick, which has half the memory requirements of the higher quality Q16 version. Check your IM's compiled Q level using "identify -version".

For medium sized images you can attempt to use "-limit" to increase the processing limits (for example processing "-limit area 8192 -limit memory 8192"), so as to try to avoid IM caching the image data to disk. However your system may reject large memory requests and still force IM to cache the image to disk (about 1000 times slower).

To see if IM is using disk cache for the image processing, you can use "-debug cache" to monitor that action.

However if you are planing to process really large images you can make sure IM does not use up all the computers memory, and slowing down the processing of other programs (by spending all its to shuffling between memory and disk swap) simply by asking it to immediately use temporary swap disk files.

For example this is a nice way of processing a very large image over a long period of time without stopping you from using your computer for other things. Basically it forces IM to cache everything to disk.

  env MAGICK_TMPDIR=/data nice -5 \
    convert -limit memory 32 -limit map 32 \
            huge_9Gb_file.psd  -scene 1 +adjoin layer_%d.png

Of course this assumes that "/data" has enough file and disk space to handle the images memory requirements.

If you have many operations to perform on the same source image and you have plenty of disk space you can use the MPC image format which is expensive to create but has near zero overhead when loading...

  convert mybigassimage.jpg mybigassimage.mpc
  convert mybigassimage.mpc   -resize 50%  resized.jpg
  convert mybigassimage.mpc   -rotate 90   rotated.jpg
  rm -f mybigassimage.mpc mybigassimage.cache

This will let you read a very large image multiple times with a minimal cost, and memory usage. Basically the format consists of two files, a informational ".mpc" file, and a direct memory paged copy of the image in a ".cache". Of course you need to clean up two files with this format then finished.

This method is designed so that IM does not have to reparse the image format to use it making it next to instant for making it available to IM in memory, though when processing it still needs to read it from disk rather than memory.

If you plan to process a very large MPC copy of the image, you must extract or crop a smaller section of the image for actual processing. This is because just about any operation performed on an image, will generally result in a new in-memory copy being made of the result, so an initial crop is a very good idea.

If you have the memory you can also try to use a 'memory disk' such as a 'TMPFS' type filesystem commonly used on Solaris systems. Be warned however that filling that type of disk also fills your computers memory.

If you have tried this method, please let me know how it went and how successful you were.

Processing Images in small sections

You can use the MPC method above to crop out various sections from a source image for further processing. However that still means you need to read in and write out the image in MPC format.

IM has also evolved a simpler pipeline processor for images called "stream". This program has a limited set of image operations that are designed to only process images one scan line (row of pixels) at a time. As such only enough memory to hold a single line of pixels is used when processing images in this way.

For example this allows you to extract a smaller area of a very large image for further processing, without needing to read in the whole image into memory first. However the output of "stream" is raw RGB image values, so some post-processing is recommended.

  stream -map rgb -storage-type char -extract 600x400+1900+2900 image.png - |\
    convert -depth 8 -size 600x400 rgb:- tileimage.png

You don't have the save the output to a file but can continue processing the smaller image directly. For example...

  stream -map rgb -storage-type char -extract 600x400+1900+2900 image.png - |\
    convert -depth 8 -size 600x400 rgb:-  ...more_processing_here...  tile.png

This will only process the 600x400 pixel image extracted without reading in the whole larger image first.

Note from Peter V <>:  In my experience is the approach of using "stream" for cutting 800MB PNM files the fastest compared to use of MPC files, or using "convert -crop".

Additional note from Jenny Drake < jennydrake @ >

You may also like to look at the non-IM alternative of "Vips" and "nip", developed by the National Portrait Gallery in London, which is designed to work on very large image files (generally TIFF) with low specification computers. "Vips" is the underlying engine and "nip" is the gui. Works on Linux, Windows and sometimes on Mac.

The older 'NetPBM' image processing suite, generally also processes images in a pipeline programming style, just as "stream" does. It is an inherent part of that library, but with the serious limitation of using a specific file format for the image.

That library is also much more limited in what it is able to do in terms of image processing, making image processing scripts much more complex.

If anyone out there does compare IM with NetPBM, say for 'crop' or 'extract' from a large image, can you please let us know what you found.

Created: 27 October 2005 (separated from 'basics' page)
Updated: 29 July 2008
Author: Anthony Thyssen, <>
Examples Generated with: [version image]