Reading the ImageMagick Docs
I want to do a deeper dive into ImageMagick to see what is possible, what the common commands look like, and to just learn more in general about it. I plan to create a Lambda Layer with ImageMagick, and I want to learn more about the tool to see what the capabilities of the layer should be before implementing it. What query parameters should the layer have? What shoudl I keep in mind? etc.
Resources
- Link to the ImageMagick Docs
- Most Recent Version of ImageMagick (7.1.1-33)
- ImageMagick Software Repository
- Some Examples of What ImageMagick can Do
- Fred's ImageMagick Scripts for Geometric Transforms
- Run ImageMagick Commands without Installing Software
- ImageMagick Community Discussions
- Anthony Thyssen's tutorial on how to use ImageMagick utilities
- A link to the Magick++ tutorial
- Magick++ Discussion forum
Introduction
ImageMagick is a free, open-source software suite, used for editing and manipulating digital images/ It can be use to create, edit, compose, or convert bitmap images, and supports a wide range of file formats, including JPEG, PNG, GIF, TIFF, and Ultra HDR.
ImageMagick is used in industries such as web development, graphic design, and video editing, as well as in scientific research, medical imaging, and astronomy. It's versatile and customizable by nature, along with its robust image processing capabilities, make it a popular choice for a wide range of image-related tasks.
- Uses command-line interface for executing complex image processing tasks
- Has APIs for integrating its features into software applications
- Written in C and can be used on a variety of operating systems, including Linux, Windows, and macOS
- Creating a security policy that fits your specific local environment before making use of ImageMagick is highly advised. You can find guidance on setting up this policy here and validate the policy using this validation tool.
Installing ImageMagick
- ImageMagick can be installed on Linux, macOS, and Windows
- NOTE: There are slightly different commands for running ImageMagick on Windows, Linux, and macOS. NOTE: Use double quotes (") rather than a single quote (') for the ImageMagick command line under Windows
magick "c:/myimages/image.png" "c:/myimages/image.png"
- I am running ImageMagick on Windows. To verify that ImageMagick has been properly installed on Windows, run the following from the command line:
> magick logo: logo.gif # Saves a logo to the directory
> magick identify logo.gif
logo.gif GIF 640x480 640x480+0+0 8-bit sRGB 256c 28576B 0.000u 0:00.000
ImageMagick Usage / General info
- ImageMagick's support for scripting and automation allows users to create complex image manipulation pipelines that can especially useful for tasks that require the processing of large numbers of images or tasks that need to be performed on a regular basis.
- Look at this page to see what libraries can be used to utilize ImageMagick from various programming languages
- The ImageMagick command-line tools exit with a status of 0 if the command line arguments have proper syntax and no problems are encountered. Expect a descriptive message and an exit status of 1 if any exception occurs such as improper syntax, a problem reading or writing an image, or any other problem that prevents the command from completing successfully.
- A minimum of 512 MB of RAM is recommended to use ImageMagick, but the more RAM the better. Although ImageMagick can run on a single core computer, it tries to run in parallel on multi-core systems reducing run times considerably.
Command Line Tools
magick
- Use this command to convert between image formats as well as resize, blur, crop, despeckle, dither, draw on, flip, join, re-sample (changing the pixel dimensions), and much more.
- Despeckle filter removes noise from images without blurring edges. It attempts to detect complex areas and leave these intact while smoothing areas where noise will be noticeable.
- Dither is an intentionally applied form of noise used to randomize quantization error, preventing large-scale patterns such as color banding in images. Dither is routines used in processing of both digital audio and video data, and is often one of the last stages of mastering audio to a CD
- A common use of dither is converting grayscale image to black and white, such that the density of black dots in the new image approximates the average gray level in the original.
Image Noise is a random variation of brightness or color information in images, and is usually an aspect of electronic noise. Image noise can range from almost imperceptible specks on a digital photograph taken in good light, to optical and radioastronomical images that are almost entirely noise, The example below shous noise clearly visible in an image from a digital camera
.
# Convert image format
magick ImageMagick_logo.svg.png ImageMagick_logo.webm
# Resize Image before it is weitten to the png format
magick ImageMagick_logo.webm -resize 50% ImageMagick_50.webm
# Combine multiple image processing results to create complex results
magick -size 320x85 canvas:none -font Bookman-DemiItalic -pointsize 72 -draw "text 25,60 'Magick'" -channel RGBA -blur 0x6 -fill darkred -stroke magenta -draw "text 20,55 'Magick'" fuzzy-magick.png
- The
magick
command has many options that you can look through.
- Use the
magick-script
scripting language to basically do the same thing as themagick
command above but in a shell script
Subcommands:
- Use the
animate
program to animate an image sequence on any X server.
- Use the
comapre
program to mathematically and visually annotate the difference between an image and its reconstruction. - We can get an output image or get a mathematical measure of the differences between images
- Use the
composite
program to overlap one image over another. You can also use this command to create a 3-dimensional affect.
- The
conjure
program gives you the ability to perform custom image processing tasks from a script written in the Magic Scripting Language (MSL). MSL is XML-based and consists of action statements with attributes.
Example:
magick conjure -dimensions 400x400 msl:incantation.sml
<?xml version="1.0" encoding="UTF-8?>
<image>
<read filename="image.gif">
<get width="base-width" height="base-height" />
<resize geometry="%[dimensions]" />
<get width="resize-width" height="resize-height" />
<print output="Image sized from %[base-width]x%[base-height] to %[resize-width]x%[resize-height].\n" />
<write filename="image.png" />
</image>
- Seems to be the same as the
magick
command
- Use the
display
program to display an image sequence on any X server.
- The
magick identify
program described the format and characteristics of one or more image files. It also reports if an image is incomplete or corrupt. The information returned includes the image number, the file name, the width and height of the image, whether the image id color mapped or not, the number of colors in the image, the number of bytes in the image, the format of the image, and finally the number of seconds it took to read and process the image. - By default,
magick identify
provides the following output:
Filename[frame \#] image-format widthxheight page-widthxpage-height+x-offset+y-offset colorspace user-time elapsed-time
- Use the
-verbose
option to get more information/metadata about the image
- Use the
import
program to capture some or all of an X server screen and save the image to a file.import
captures the window selected by clicking or program argument.
- Use the
magick mogrify
program to basically do the same thing as themagick
command, except the original file is overwritten in this case (unless you change the file format with teh-format
option).
- Use the
montage
program to create a composite image by combining serveral separate images. The images tiles on the composite image optionally adorned with a border, frame, image name, and more.
Examples:
magick montage -background '#336699' -geometry +4+4 rose.jpg red-ball.png montage.jpg
magick montage -label %f -frame 5 -background '#336699' -geometry +4+4 rose.jpg red-ball.png frame.jpg
stream
is a lightweight tool to stream one or more pixel components of the image or portion of the image to your choice of storage formats, It writes the pixel components as they are read from the input image a row at a time makingstream
desirable when working with larger images or when you require raw pixel components.
Command Line Processing
- ImageMagick can be used for simple file conversions
- Adding a three-dimensional look to a 2-D image
- Or it can be used to create a complex graphic from an empty canvas:
The Anatomy of the Command Line
- The ImageMagick command-line consists of:
- One or more required input filenames
- zero, one or more image settings
- zero, one or more image operators
- zero, one or more image sequence operators
- zero, one or more image stacks
- zero, one or more output filenames
Input Filename
ImageMagick extends the concept of an input filename to include:
- filename globbing
- an explicit image format
- using built-in images and patterns
- STDIN, STDOUT, and file descriptors
- selecting certain frames from an image
- selection a region of an image
- forcing an inline image resize
- forcing an inline image crop
- using filename references
Filename Globbing
In Linux shells, certain characters such as the asterisk (*) and question mark (?) automatically cause lists of filenames to be generated based on pattern matches. This feature is known as globbing. ImageMagick supports globbing on systems that do not natively support it, such as Windows. The example below shows grouping all files with a jpg extension into a GIF animation:
magick *.jpg images.gif
Explicit Image Format
Images are stored in a myriad of image formats like JPG, PNG, etc.. ImageMagick must know the format of the image before it can be read and processed. Most formats have a signature withing the image that uniquely identifies the format. Failing that, ImageMagick leverages the filename extension to determine the format. Sometimes, the image format has to be automatically specified.
Built-in Images and Patterns
ImageMagick has a number of built-in images and patterns.
STDIN, STDOUT, and file descriptors
Linux and Windows permit the output of one command to be piped to the input of another. ImageMagick permits image data to be read and written from the standard streams STDIN and STDOUT using a pseudo-filename -
. Example:
magick logo: gif:- | magick display gif:-
Selecting Frames
Some image formats contain more than one image frame. Perhaps you only want the first image, or the last, or some in between. You can select a single frame or a range of frames. NOTE: Single quotes are used in Linux and double quotes in Windows typically.
# Selecting a single image
magick 'images.gif[0]' image.png
# Selecting multiple frames of images
magick 'images.gif[0-3]' images.mng
magick 'images.gif[3,2,4]' images.msg
Selecting an Image Region
Raw image are a sequence of color intensities without additional meta information such as width, height, or image signature.
Inline Image Resize
It is sometimes convenient to resize an image as they are read. Suppose you have hundreds of large JPEG images you want to convert to a sequence of PNG thumbnails:
# Convert hundreds of large JEPG images into a seuqence of PNG thumbnails
magick '*.jpg' -resize 120x120 thumbnail%03d.png
Inline Image Crop
It is sometimes convenient to crop an image as they are read.
Filename References
There are some methods to use a filename to reference image filenames.
Stream Buffering
By default, the input stream is buffered. to ensure information on the source file or terminal is read as soon as it is available, set the buffer size to 0:
magick logo: gif:- | magick display -define stream:buffer-size=0 gif:-
Command-line Options
You can direct the behavior of ImageMagick utilities with command line options. The options fall into one of the categories defined below.
- Image Setting
- An image setting persists as it appears on the command-line and may affect subsequent processing such as reading an image, an image operator, or when writing an image as appropriate.
- An image setting stays into effect until it is reset or the command line terminates. The image settings include:
-adjoin
- Image Operator
- An image operator differs from a setting in that it affects the image immediately as it appears on the command-line. An operator is any command-line option not listed as an image setting or image sequence operator.
- Unlike an image setting, which persists until the command-line terminated, an operator is applies to the current image set and forgotten.
- Image Channel Operator
- Operate directly on image channels
- Image Sequence Operator
- An image sequence operator differs from a setting in that it affects an image sequence immediately as it appears on the command-line.
- Image Geometry
- Many command line options take a geometry argument to specify such things as the desired width and height of an image and other dimensional quantities. Because users want so many variations on the resulting dimensions, sizes, and positions of images, the geometry argument can take many forms.
- The geometry argument might take any of the forms listed in the table below. These will be described in more detail in the subsections following the table. The usual form is size[offset], meaning size is required and offset is optional. Occasionally, [side]offset is possible.
size | General Description (actual behavior can vary for options and settings) |
---|---|
scale% | Height and width both scaled by a certain percentage |
scale-x%scale-y% | Height and width individually scaled by specified percentages (Only one % symbol needed) |
width | Width given, height automatically selected to preserve aspect ratio |
xheight | Height given, width automatically selected to preserve aspect ratio |
widthxheight | Maximum values of height and width given, aspect ratio preserved |
widthxheight^ | Maximum values of width and height given, aspect ratio preserved |
widthxheight! | Width and height emphatically given, original aspect ratio ignored |
widthxheight> | Shrinks an image with dimension(s) larger that the corresponding width and/or height arguments |
widthxheight< | Enlarges an image with dimension(s) smaller than the corresponding width and/or height arguments |
area@ | Resize an image to have specified area in pixels. Aspect ratio is preserved. |
x:y | Here x and y denotes an aspect ratio |
x:y^ | Remove rows or columns to achieve the given aspect ratio |
x:y# | add rows or columns to achieve the given aspect ratio |
{size}{offset} | Specifying the offset (default is +0+0). below, {size} referes to any of the forms above. |
{size}{+-}x{+-}y | Horizontal and vertical offsets x and y, specified in puxels. Signs are required for both. Offsets are not affected by % or other size operators. Note that positive X and Y offsets are in the inward direction towards the center of the image for all -gravity options, except 'center'. For East, +X is left. For South, +Y is up. For SouthEast, +X is left and +Y is up. For center, the normal X and Y directional convention is used (+X is right and +Y is down). |
If an image is 640 pixels wide and 480 pixels high, we say its dimensions are 640x480. When we give the dimensions of an image, the width (horizontal dimension) always precedes the height (the vertical dimension). This will be true when we speak of coordinates or offsets into an image, which will always be x-value followed by y.
By default, the width and height given in a geometry argument are the maximum values unless a percentage is specified. That is, the image is expanded or contracted to fit the specified width and height value while maintaining the aspect ratio (the ratio of its height to its width) of the image.
You can change this behavior with the ^
and !
characters.
A typical use of offsets is in conjunction with the -region
option. Offsets start at (0,0) (upper left hand corner of the image).
Examples:
# Scale whole thig by factor of 2
magick logo: -resize '200%' bigWiz.png
# stretch the width 200% and squash the height by 50%
magick logo: -resize '200x50%' longShortWiz.png
# Resize an image to maximum 100 width 200 height px, preserve aspect ratio
magick logo: -resize '100x200' notThinWiz.png
# Resize an image to minimum 100 width 200 height px, preserve aspect ratio
magick logo: -resize '100x200^' biggerNotThinWiz.png
# Resize an image to maximum 100 width 200 height px
magick logo: -resize '100x200!' dochThinWiz.png
# Resize an image to maximum 100 width px, preserve aspect ratio
magick logo: -resize '100' wiz1.png
# Resize an image to maximum 200 height px, preserve aspect ratio
magick logo: -resize 'x200' wiz2.png
# Shrink an image to maximum 100x200 px only if dimensions are larger than 100x200
magick logo: -resize '100x200>' wiz3.png
# Enlarge an image to 100x200 only if dimensions are smaller than 100x200
magick logo: -resize '100x200<' wiz4.png
# Puts the 100x200 rectangle's own upper left corner at (10,20)
magick logo: -region '100x200+10+20' -negate wizNeg1.png
# Sometimes negative offset makes sense
magick logo: -region '100x200-10+20' -negate wizNeg2.png
# The -gravity setting precedes the others and sets the current location with the image at teh very center of the image
magick logo: -gravity center -region '100x200-10+20' -negate wizNeg3.png
- Look into ImageStack when you need to perform operations on an image sequentially
Output Filename
ImageMagick extends the concept of an output filename to include:
- an explicit image format
- write to standard out
- filename references
Explicit Image Format
- Basically the same rules as input image format. If ImageMagick can not determine what the output image format should be by the name of the output image file, then you must specify it explicitly.
Standard Out
- ImageMagick permits piping one command to another with a filename of
-
.
Filename References
- Goes over using a list of image filenames defined in a file.
Command Line Options
- There are about 313 different ImageMagick options, so I'm not going to go through them all here. I will come back to this and describe options in more detail when I find them useful.
The ImageMagick Graphics Library
A gentle introduction to Magick++
The Magick++ library is a set of C++ wrapper classes that provides access to the ImageMagick package functionality from within a C++ application.
The Magick++ library can perform the following classes of operations on images:
- create new images, or read existing images
- edit images: flip, mirror, rotate, scale, transform images, adjust image colors, apply various special effects, or draw text, lines, polygons, arcs ellipses, and Bezier curves
- compose new images based on other images
- save images in a variety of formats, including GIF, JPEG, SVG, and PostScript
In object oriented graphics, an image (also known as a 'digital image') is described by an object featured with a self rendering method. In the Magick++ implementation, each such image object always has an associated canvas which actually holds the picture data.
What is a canvas?
- A canvas can be described from several perspectives:
- From visual point of view, a canvas represents a virtual surface where an application can draw, paint or paste pieces of image
- From the point of view of the internal representation, the canvas is stored as an array of pixels (also known as a bitmap), with each pixel stored in a certain format (usually based on the Red-Green-Blue-Alpha components, but other pixel formats may also be implemented).
The Geometry Class
- The geometry class is used mostly for specifying the size of a rectangular object
Geometry::Geometry(unsigned int x, unsigned int y);
Geometry::Geometry(const String& geometry);
// examples
Geometry g1(100,200); // numeric constructor
Geometry g2("300x400"); // string constructor
Pixels in Magick++ Library
- The data format of the pixel is of type 'PixelPacket'. The 'PixelPacket' is a C C structure used to represent pixels. The PixelPacket members are:
- 'red'
- 'green'
- 'blue'
- 'opacity': this PixelPacket member defines the "opacity" of the pixel, thus an image to include the transparency information (an example of image file format that is able of preserving the image transparency information is the PNG format)
Quantizing Levels
- Each member of the PixelPacket structure is an unsigned integer number, and depending on how the packet was compiled, it may be implemented on 8 bits or 16 bits (i.e. the total size of a PixelPacket is 48=32 bits or 416=64 bits); thus, the number of quantizing levels for each of the PixelPacket components can be 2^8=256 or 2^16=65536.
The Color Class
- The Magick++ library provides a class 'Color' that is used by a number of Magick++ methods that set the color attribute of various graphical operations.
the Magick++ Image Object
The Image Class
- A Magick++ Image is a special object that implements a number of characteristic features:
- It has methods for self-rendering on an output interface ( a computer screen, a file, etc)
- It has an associated canvas, where the canvas is the data storage area use to hold the picture data that the image object can render
- It has a set of specific methods that allow various ways to access the canvas of the Image such that the picture can be modified
- It can be used in conjunction with other Image objects in order to create new composite images
The Canvas Format
- The Magick++ Image canvas is stored internally as a contiguous array of pixels, where each pixel is a structure of type "PixelPacket"
Transparency
- The opacity component of a PixelPacket is used when combining multiple image elements on the same canvas
- Examples:
- When a green line is drawn over a red background, if the red background is totally opaque and the green line has 50% opacity then the resulting line will actually have a "grayish yellow" color
- Similarly, when placing a semitransparent image over an opaque image, the resulting image will be a blending of the colors coming from both images (based on the opacity values involved in the pixel by pixel blending process)
- Limitations:
- Magick++ library functions can load images that contain transparency information if their format is GIF or PNG
- Magick++ library functions can preserve the transparency information if the save format PNG
Creating an Image
// create an mpty-canvas image
// this is *not* a "blnk" image, it's a completely empty as its canvas has 0x0 dimensions
Image empty_image()
// create a blank image canvas with 640x480 size and 'white' color as background:
Image blank_image( Geometry(640, 480), Color(MaxRGB, MaxRGB, MaxRGB, 0));
// or also, by using the automatic C++ type conversions for the arguments:
Image blank_image("640x480", "white");
Accessing Image Attributes
// Canvas Geometry
unsigned int Image::columns(); // returns an unsigned int representing the my_image width
unsigned int Image::rows(); // returns an unsigned int representing the my_image heigth
// the image Format
// this attribute is *not* related to the internal representation of the image on canvas,
// which is always a PixelPacket array;
// it is automaticlally set when reading an image based on the image encoding
// or it can be set within the program
void Image::magick(const string& image_format);
// sets the my_image format;
// the format string can be "GIF", etc
string Image::magick(); // returns a string value representing the
// image format (e.g. “GIF”, “JPEG”, etc)
Getting Direct Access to the Canvas Pixels
// set or get the color for the pixel at position (x,y) on the canvas
void Image::pixelColor(unsigned int x, unsigned int y, const Color& color);
Color Image::pixelColor(unsigned int x, unsigned int y);
// Example: setting pixels
Image my_image("640x480", "white");
// start with creating a white-background
canvas my_image.pixelColor(50,50,Color("red"));
// set the pixel at position (50,50) to red
my_image.pixelColor(5,5,Color(MaxRGB,0,0,MaxRGB/2)); // set semitransparent red at (5,5)
Blobs: storing encoded images in Memory
- Encoded images are most often written-to and read-from a disk file, but they may also reside in memory. Encoded images in memory are also known as BLOBs - Binary Large Objects. Magick++ provides the 'Blob' class for representing images that are stored in memory in encoded format.
Drawing Functionality
- I will come back to this when/if I need to.
Global Image Operations
- Overlaying Images
- Use the
Image::composite()
method to overlay images
- Use the
- Extract a "sub-image" from another image
- Magick++ supports the extraction of a "sub-image" from another image via two Image methods:
chop()
andcrop()
. Both these methods resize the image canvas that they operate on by keeping only a certain region of the original, and simply discarding the rest. The region that will be retained is specific to each method.
- Magick++ supports the extraction of a "sub-image" from another image via two Image methods:
Global Image Modifications
- Magick++ provides functionality for:
- Resizing an Image with the
zoom
method - Rotating an Image with the
rotate
method - Modifying the colors of pixels by changing the colors of the pixels directly
- Blurring an Image with the
blur
method
- Resizing an Image with the
Comments
There are currently no comments to show for this article.