What is the difference between ImageMagick and GraphicsMagick?

QbProg picture QbProg · May 14, 2009 · Viewed 21.9k times · Source

I've found myself evaluating both of these libs. Apart from what the GraphicsMagick comparison says, I see that ImageMagick still got updates and it seems that the two are almost identical.

I'm just looking to do basic image manipulation in C++ (i.e. image load, filters, display); are there any differences I should be aware of when choosing between these libraries?

Answer

Mark Setchell picture Mark Setchell · May 20, 2019

As with many things in life, different people have different ideas about what is best. If you ask a landscape photographer who wanders around in the rain in Scotland's mountains which is the best camera in the world, he's going to tell you a light-weight, weather-sealed camera. Ask a studio photographer, and he'll tell you the highest resolution one with the best flash sync speed. And if you ask a sports photographer he'll tell you the one with the fastest autofocus and highest frame rate. So it is with ImageMagick and GraphicsMagick.

Having answered around 2,000 StackOverflow questions on ImageMagick over the last 5+ years, I make the following observations...

In terms of popularity...

  • ImageMagick questions on SO outnumber GraphicsMagick questions by a factor of 12:1 (7,375 questions vs 611 at May 2019), and
  • ImageMagick followers on SO outnumber GraphicsMagick followers by 15:1 ((387 followers versus 25 at May 2019)

In terms of performance...

I am happy to concede that GraphicsMagick may be faster for some, but not all problems. However, if speed is your most important consideration, I think you should probably be using either libvips, or parallel code on today's multi-core CPUs or heavily SIMD-optimised (or GPU-optimised) libraries like OpenCV.

In terms of features and flexibility...

There is one very clear winner here - ImageMagick. My experience is that there are many features missing from GraphicsMagick which are present in ImageMagick and I list some of these below, in no particular order.

I freely admit I am not as familiar with GraphicsMagick as I am with ImageMagick, but I made my very best effort to find any mention of the features in the most recent GraphicsMagick source code. So, for Canny Edge Detector, I ran the following command on the GM source code:

find . -type f -exec grep -i Canny {} \;

and found nothing.


Canny Edge detector

This appears to be completely missing in GM. See -canny radiusxsigma{+lower-percent}{+upper-percent} in IM.

See example here and sample of edge-detection on Lena image:

enter image description here


Parenthesised processing, sophisticated re-sequencing

This is a killer feature of ImageMagick that I frequently sorely miss when having to use GM. IM can load, or create, or clone a whole series of images and apply different processing selectively to specific images and re-sequence, duplicate and re-order them very simply and conveniently. It is hard to convey the incredible flexibility this affords you in a short answer.

Imagine you want to do something fairly simple like load image A and blur it, load image B and make it greyscale and then place the images side-by-side with Image B on the left. That looks like this with ImageMagick:

magick imageA.png -blur x3 \( imageB.png -colorspace gray \) +swap +append result.png

enter image description here

You can't even get started with GM, it will complain about the parentheses. If you remove them, it will complain about swapping the image order. If you remove that it will apply the greyscale conversion to both images because it doesn't understand parentheses and place imageA on the left.

See the following sequencing commands in IM:

  • -swap
  • -clone
  • -duplicate
  • -delete
  • -insert
  • -reverse

fx DIY Image Processing Operator

IM has the -fx operator which allows you to create and experiment with incredibly sophisticated image processing. You can have function evaluated for every single pixel in an image. The function can be as complicated as you like (save it in a file if you want to) and use all mathematical operations, ternary-style if statements, references to pixels even in other images and their brightness or saturation and so on.

Here are a couple of examples:

magick rose: -channel G -fx 'sin(pi*i/w)' -separate   fx_sine_gradient.gif

enter image description here

magick -size 80x80 xc: -channel G -fx  'sin((i-w/2)*(j-h/2)/w)/2+.5' -separate fx_2d_gradient.gif

enter image description here

A StackOverflow answer that uses this feature to great effect in processing green-screen (chroma-keyed) images is here.


Fourier (frequency domain) Analysis

There appears to be no mention of forward or reverse Fourier Analysis in GM, nor the High Dynamic Range support (see later) that is typically required to support it. See -fft in IM.


Connected Component Analysis / Labelling/ Blob Analysis

There appears to be no "Connected Component Analysis" in GM - also known as "labelling" and "Blob Analysis". See -connected-components connectivity for 4- and 8-connected blob analysis.

This feature alone has provided 60+ answers - see here.


Hough Line Detection

There appears to be no Hough Line Detection in GM. See -hough-lines widthxheight{+threshold} in IM.

See description of the feature here and following example of detected lines:

enter image description here


Moments and Perceptual Hash (pHash)

There appears to be no support for image moments calculation (centroids and higher orders), nor Perceptual Hashing in GM. See -moments in IM.


Morphology

There appears to be no support for Morphological processing in GM. In IM there is sophisticated support for:

  • dilation
  • erosion
  • morphological opening and closing
  • skeletonisation
  • distance morphology
  • top hat and bottom hat morphology
  • Hit and Miss morphology - line ends, line junctions, peaks, ridges, Convex Hulls etc

See all the sophisticated processing you can do with this great tutorial.


Contrast Limited Adaptive Histogram Equalisation - CLAHE

There appears to be no support for Contrast Limited Adaptive Histogram Equalisation in GM. See -clahe widthxheight{%}{+}number-bins{+}clip-limit{!} in IM.


HDRI - High Dynamic Range Imaging

There appears to be no support for High Dynamic Range Imaging in GM - just 8, 16, and 32-bit integer types.


Convolution

ImageMagick supports many types of convolution:

  • Difference of Gaussians DoG
  • Laplacian
  • Sobel
  • Compass
  • Prewitt
  • Roberts
  • Frei-Chen

None of these are mentioned in the GM source code.


Magick Persistent Register (MPR)

This is an invaluable feature present in ImageMagick that allows you to write intermediate processing results to named chunks of memory during processing without the overhead of writing to disk. For example, you can prepare a texture or pattern and then tile it over an image, or prepare a mask and then alter it and apply it later in the same processing without going to disk.

Here's an example:

 magick tree.gif -flip -write mpr:tree +delete -size 64x64 tile:mpr:tree mpr_tile.gif

enter image description here


Broader Colourspace Support

IM supports the following colourspaces not found in GM:

  • CIELab
  • HCL
  • HSI
  • LMS
  • others.

Pango Support

IM supports Pango Text Markup Language which is similar to HTML and allows you to annotate images with text that changes:

  • font, colour, size, weight, italics
  • subscript, superscript, strike-through
  • justification

mid-sentence and much, much more. There is a great example here.

enter image description here


Shrink-on-load with JPEG

This invaluable feature allows the library to shrink JPEG images as they are read from disk, so that only the necessary coefficients are read, so the I/O is lessened, and the memory consumption is minimised. It can massively improve performance when down-scaling images.

See example here.


Defined maximum JPEG size when writing

IM supports the much-requested option to specify a maximum filesize when writing JPEG files, -define jpeg:extent=400KB for example.


Polar coordinate transforms

IM supports conversion between cartesian and polar coordinates, see -distort polar and -distort depolar.


Statistics and operations on customisable areas

With its -statistic MxN operator, ImageMagick can generate many useful kinds of statistics and effects. For example, you can set each pixel in an image to the gradient (difference between brightest and darkest) of its 5x3 neighbourhood:

magick image.png -statistic gradient 5x3 result.png

Or you can set each pixel to the median of its 1x200 neighbourhood:

magick image.png -statistic median 1x200 result.png

See example of application here.

enter image description here


Sequences of images

ImageMagick supports sequences of images, so if you have a set of very noisy images shot at high ISO, you can load up the entire sequence of images and, for example, take the median or average of all images to reduce noise. See the -evaluate-sequence operator. I do not mean the median in a surrounding neighbourhood in a single image, I mean by finding the median of all images at each pixel position.


The above is not an exhaustive list by any means, they are just the first few things that came to mind when I thought about the differences. I didn't even mention support for HEIC (Apple's format for iPhone images), increasingly common High Dynamic Range formats such as EXR, or any others. In fact, if you compare the file formats supported by the two products (gm convert -list format and magick identify -list format) you will find that IM supports 261 formats and GM supports 192.

As I said, different people have different opinions. Choose the one that you like and enjoy using it.

As always, I am indebted to Anthony Thyssen for his excellent insights and discourse on ImageMagick at https://www.imagemagick.org/Usage/ Thanks also to Fred Weinhaus for his examples.