Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

gm

aheckmann1.8mMITdeprecated1.25.1TypeScript support: definitely-typed

The gm module has been sunset. Please migrate to an alternative. https://github.com/aheckmann/gm?tab=readme-ov-file#2025-02-24-this-project-is-not-maintained

GraphicsMagick and ImageMagick for node.js

graphics, magick, image, graphicsmagick, imagemagick, gm, convert, identify, compare

readme

gm Build Status NPM Version

GraphicsMagick and ImageMagick for node

Bug Reports

When reporting bugs please include the version of graphicsmagick/imagemagick you're using (gm -version/convert -version) as well as the version of this module and copies of any images you're having problems with.

Getting started

First download and install GraphicsMagick or ImageMagick. In Mac OS X, you can simply use Homebrew and do:

brew install imagemagick
brew install graphicsmagick

then either use npm:

npm install gm

or clone the repo:

git clone git://github.com/aheckmann/gm.git

Use ImageMagick instead of gm

Subclass gm to enable ImageMagick 7+

const fs = require('fs')
const gm = require('gm').subClass({ imageMagick: '7+' });

Or, to enable ImageMagick legacy mode (for ImageMagick version < 7)

const fs = require('fs')
const gm = require('gm').subClass({ imageMagick: true });

Specify the executable path

Optionally specify the path to the executable.

const fs = require('fs')
const gm = require('gm').subClass({
  appPath: String.raw`C:\Program Files\ImageMagick-7.1.0-Q16-HDRI\magick.exe`
});

Basic Usage

var fs = require('fs')
  , gm = require('gm');

// resize and remove EXIF profile data
gm('/path/to/my/img.jpg')
.resize(240, 240)
.noProfile()
.write('/path/to/resize.png', function (err) {
  if (!err) console.log('done');
});

// some files would not be resized appropriately
// http://stackoverflow.com/questions/5870466/imagemagick-incorrect-dimensions
// you have two options:
// use the '!' flag to ignore aspect ratio
gm('/path/to/my/img.jpg')
.resize(240, 240, '!')
.write('/path/to/resize.png', function (err) {
  if (!err) console.log('done');
});

// use the .resizeExact with only width and/or height arguments
gm('/path/to/my/img.jpg')
.resizeExact(240, 240)
.write('/path/to/resize.png', function (err) {
  if (!err) console.log('done');
});

// obtain the size of an image
gm('/path/to/my/img.jpg')
.size(function (err, size) {
  if (!err)
    console.log(size.width > size.height ? 'wider' : 'taller than you');
});

// output all available image properties
gm('/path/to/img.png')
.identify(function (err, data) {
  if (!err) console.log(data)
});

// pull out the first frame of an animated gif and save as png
gm('/path/to/animated.gif[0]')
.write('/path/to/firstframe.png', function (err) {
  if (err) console.log('aaw, shucks');
});

// auto-orient an image
gm('/path/to/img.jpg')
.autoOrient()
.write('/path/to/oriented.jpg', function (err) {
  if (err) ...
})

// crazytown
gm('/path/to/my/img.jpg')
.flip()
.magnify()
.rotate('green', 45)
.blur(7, 3)
.crop(300, 300, 150, 130)
.edge(3)
.write('/path/to/crazy.jpg', function (err) {
  if (!err) console.log('crazytown has arrived');
})

// annotate an image
gm('/path/to/my/img.jpg')
.stroke("#ffffff")
.drawCircle(10, 10, 20, 10)
.font("Helvetica.ttf", 12)
.drawText(30, 20, "GMagick!")
.write("/path/to/drawing.png", function (err) {
  if (!err) console.log('done');
});

// creating an image
gm(200, 400, "#ddff99f3")
.drawText(10, 50, "from scratch")
.write("/path/to/brandNewImg.jpg", function (err) {
  // ...
});

Streams

// passing a stream
var readStream = fs.createReadStream('/path/to/my/img.jpg');
gm(readStream, 'img.jpg')
.write('/path/to/reformat.png', function (err) {
  if (!err) console.log('done');
});


// passing a downloadable image by url

var request = require('request');
var url = "www.abc.com/pic.jpg"

gm(request(url))
.write('/path/to/reformat.png', function (err) {
  if (!err) console.log('done');
});


// can also stream output to a ReadableStream
// (can be piped to a local file or remote server)
gm('/path/to/my/img.jpg')
.resize('200', '200')
.stream(function (err, stdout, stderr) {
  var writeStream = fs.createWriteStream('/path/to/my/resized.jpg');
  stdout.pipe(writeStream);
});

// without a callback, .stream() returns a stream
// this is just a convenience wrapper for above.
var writeStream = fs.createWriteStream('/path/to/my/resized.jpg');
gm('/path/to/my/img.jpg')
.resize('200', '200')
.stream()
.pipe(writeStream);

// pass a format or filename to stream() and
// gm will provide image data in that format
gm('/path/to/my/img.jpg')
.stream('png', function (err, stdout, stderr) {
  var writeStream = fs.createWriteStream('/path/to/my/reformatted.png');
  stdout.pipe(writeStream);
});

// or without the callback
var writeStream = fs.createWriteStream('/path/to/my/reformatted.png');
gm('/path/to/my/img.jpg')
.stream('png')
.pipe(writeStream);

// combine the two for true streaming image processing
var readStream = fs.createReadStream('/path/to/my/img.jpg');
gm(readStream)
.resize('200', '200')
.stream(function (err, stdout, stderr) {
  var writeStream = fs.createWriteStream('/path/to/my/resized.jpg');
  stdout.pipe(writeStream);
});

// GOTCHA:
// when working with input streams and any 'identify'
// operation (size, format, etc), you must pass "{bufferStream: true}" if
// you also need to convert (write() or stream()) the image afterwards
// NOTE: this buffers the readStream in memory!
var readStream = fs.createReadStream('/path/to/my/img.jpg');
gm(readStream)
.size({bufferStream: true}, function(err, size) {
  this.resize(size.width / 2, size.height / 2)
  this.write('/path/to/resized.jpg', function (err) {
    if (!err) console.log('done');
  });
});

Buffers

// A buffer can be passed instead of a filepath as well
var buf = require('fs').readFileSync('/path/to/image.jpg');

gm(buf, 'image.jpg')
.noise('laplacian')
.write('/path/to/out.jpg', function (err) {
  if (err) return handle(err);
  console.log('Created an image from a Buffer!');
});

/*
A buffer can also be returned instead of a stream
The first argument to toBuffer is optional, it specifies the image format
*/
gm('img.jpg')
.resize(100, 100)
.toBuffer('PNG',function (err, buffer) {
  if (err) return handle(err);
  console.log('done!');
})

Custom Arguments

If gm does not supply you with a method you need or does not work as you'd like, you can simply use gm().in() or gm().out() to set your own arguments.

  • gm().command() - Custom command such as identify or convert
  • gm().in() - Custom input arguments
  • gm().out() - Custom output arguments

The command will be formatted in the following order:

  1. command - ie convert
  2. in - the input arguments
  3. source - stdin or an image file
  4. out - the output arguments
  5. output - stdout or the image file to write to

For example, suppose you want the following command:

gm "convert" "label:Offline" "PNG:-"

However, using gm().label() may not work as intended for you:

gm()
.label('Offline')
.stream();

would yield:

gm "convert" "-label" "\"Offline\"" "PNG:-"

Instead, you can use gm().out():

gm()
.out('label:Offline')
.stream();

which correctly yields:

gm "convert" "label:Offline" "PNG:-"

Custom Identify Format String

When identifying an image, you may want to use a custom formatting string instead of using -verbose, which is quite slow. You can use your own formatting string when using gm().identify(format, callback). For example,

gm('img.png').format(function (err, format) {

})

// is equivalent to

gm('img.png').identify('%m', function (err, format) {

})

since %m is the format option for getting the image file format.

Platform differences

Please document and refer to any platform or ImageMagick/GraphicsMagick issues/differences here.

Examples:

Check out the examples directory to play around. Also take a look at the extending gm page to see how to customize gm to your own needs.

Constructor:

There are a few ways you can use the gm image constructor.

  • 1) gm(path) When you pass a string as the first argument it is interpreted as the path to an image you intend to manipulate.
  • 2) gm(stream || buffer, [filename]) You may also pass a ReadableStream or Buffer as the first argument, with an optional file name for format inference.
  • 3) gm(width, height, [color]) When you pass two integer arguments, gm will create a new image on the fly with the provided dimensions and an optional background color. And you can still chain just like you do with pre-existing images too. See here for an example.

The links below refer to an older version of gm but everything should still work, if anyone feels like updating them please make a PR

Methods

compare

Graphicsmagicks compare command is exposed through gm.compare(). This allows us to determine if two images can be considered "equal".

Currently gm.compare only accepts file paths.

gm.compare(path1, path2 [, options], callback)
gm.compare('/path/to/image1.jpg', '/path/to/another.png', function (err, isEqual, equality, raw, path1, path2) {
  if (err) return handle(err);

  // if the images were considered equal, `isEqual` will be true, otherwise, false.
  console.log('The images were equal: %s', isEqual);

  // to see the total equality returned by graphicsmagick we can inspect the `equality` argument.
  console.log('Actual equality: %d', equality);

  // inspect the raw output
  console.log(raw);

  // print file paths
  console.log(path1, path2);
})

You may wish to pass a custom tolerance threshold to increase or decrease the default level of 0.4.

gm.compare('/path/to/image1.jpg', '/path/to/another.png', 1.2, function (err, isEqual) {
  ...
})

To output a diff image, pass a configuration object to define the diff options and tolerance.

var options = {
  file: '/path/to/diff.png',
  highlightColor: 'yellow',
  tolerance: 0.02
}
gm.compare('/path/to/image1.jpg', '/path/to/another.png', options, function (err, isEqual, equality, raw) {
  ...
})

composite

GraphicsMagick supports compositing one image on top of another. This is exposed through gm.composite(). Its first argument is an image path with the changes to the base image, and an optional mask image.

Currently, gm.composite() only accepts file paths.

gm.composite(other [, mask])
gm('/path/to/image.jpg')
.composite('/path/to/second_image.jpg')
.geometry('+100+150')
.write('/path/to/composite.png', function(err) {
    if(!err) console.log("Written composite image.");
});

montage

GraphicsMagick supports montage for combining images side by side. This is exposed through gm.montage(). Its only argument is an image path with the changes to the base image.

Currently, gm.montage() only accepts file paths.

gm.montage(other)
gm('/path/to/image.jpg')
.montage('/path/to/second_image.jpg')
.geometry('+100+150')
.write('/path/to/montage.png', function(err) {
    if(!err) console.log("Written montage image.");
});

Contributors

https://github.com/aheckmann/gm/contributors

Inspiration

http://github.com/quiiver/magickal-node

Plugins

https://github.com/aheckmann/gm/wiki

Tests

npm test

To run a single test:

npm test -- alpha.js

License

(The MIT License)

Copyright (c) 2010 Aaron Heckmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

changelog

1.25.0 / 2022-09-21

  • fixed: windows support #846, #774, #594, #524, #528, #559, #652, #682 piotr-cz
  • docs; improvements from #821 agokhale
  • docs; improvements #801 aarongarciah

1.24.0 / 2022-09-18

  • fixed: infering format of buffered or streamed ico files #429 freund17
  • fixed; preserve color info duing autoOrient() #714, #844 reco
  • tests; switch to Github Actions
  • docs; fix links #834 delesseps
  • docs; clarify install directions #689 PatrykMiszczak
  • refactor; clean up compare.js #788 LongTengDao

1.23.1 / 2017-12-27

  • fixed: use debug > 2.6.9 because of security issue #685 danez
  • tests; add nsp check
  • tests; get tests passing on OSX

1.23.0 / 2016-08-03

  • fixed; webpack support #547 sean-shirazi
  • fixed; windows support - use cross-spawn to spawn processes #537 bdukes
  • added; allow thumbnail to accept the same options as resize #527 Sebmaster
  • added; dispose support #487 dlwr
  • docs; add example of loading image from URL #544 wahengchang
  • docs; Fix a link in README.md #532 clbn
  • travis; update travis versions #551 amilajack

1.22.0 / 2016-04-07

  • fixed; identity parser: support multi-value keys by creating an array #508 #509 emaniacs
  • fixed; error handling if gm is not installed #499 aeo3
  • fixed; highlightColor typo in compare #504 DanielHudson
  • docs; Fix typo #475 rodrigoalviani

1.21.1 / 2015-10-26

  • fixed: Fixed #465 hard coded gm binary, also fixed issues with compare and fixed tests so they will fail on subsequent runs when they should do rwky

1.21.0 / 2015-10-26 contains security fix

  • fixed: gm.compare fails to escape arguments properly (Reported by Brendan Scarvell) rwky

1.20.0 / 2015-09-23

  • changed: Reverted "Add format inference from filename for buffers/streams" due to errors #448

1.19.0 / 2015-09-16

  • changed: Added error to notify about image magick not supporting minify encima
  • changed: Refactored orientation getter to use faster identify call lbeschastny
  • added: resizeExact function DanMMX
  • added: thumbExact function DanMMX
  • added: Add format inference from filename for buffers/streams adurrive
  • fixed: Hex values when passed to compare aren't quoted automatically DanMMX
  • fixed: identify returning last frame size instead of the larges on animated gifs preynal
  • docs: Updated docs laurilehmijoki

1.18.1 / 2015-05-18

  • changed: Added io.js support rwky

1.18.0 / 2015-05-18

  • changed: Removed support for node 0.8 and added support for 0.12 rwky
  • changed: Listen to stdin error event for spawn errors kapouer
  • changed: Improved error handling when gm isn't installed FreshXOpenSource
  • changed: Allow append method to use an array of arguments emohacker
  • changed: appPath option now specifies full path to gm binary John Borkowski
  • changed: Ignore warning messages for identify asrail
  • added: Montage method donaldpcook
  • added: Progressive option to thumb mohebifar
  • added: Native gm auto-orient for use with gm >= 1.3.18 bog
  • added: Timeout support by passing the timeout option in milliseconds marcbachmann
  • fixed: density when using ImageMagick syzer
  • fixed: resize behaviour for falsy values adius

1.17.0 / 2014-10-28

  • changed: extended compare callback also returns the file names #297 mastix
  • changed: pass spawn crash to callback #306 medikoo
  • changed: geometry supports arbitary string as first argument #330 jdiez17
  • added: support for repage+ option #275 desigens
  • added: added the dissolve command #300 microadm
  • added: composite method #332 jdiez17
  • fixed: cannot set tolerance to 0 #302 rwky
  • fixed: handle empty buffers #330 alcidesv

1.16.0 / 2014-05-09

  • fixed; dropped "+" when 0 passed as vertical roll amt #267 dwtkns
  • added; highlight-style support #272 fdecampredon

1.15.0 / 2014-05-03

  • changed; gm.compare logic to always run the mse comparison as expected #258 Vokkim
  • added; tolerance to gm.compare options object #258 Vokkim
  • added; option to set ImageMagick application path explicitly #250 (akreitals)
  • fixed; gm.compare: support values like 9.51582e-05 #260 normanrz
  • README: add call for maintainers

1.14.2 / 2013-12-24

  • fixed; background is now a setting #246 (PEM--)

1.14.1 / 2013-12-09

  • fixed; identify -verbose colon behavior #240 ludow

1.14.0 / 2013-12-04

  • added; compare method for imagemagick (longlho)

1.13.3 / 2013-10-22

  • fixed; escape diffOptions.file in compare (dwabyick)

1.13.2 / 2013-10-18

  • fixed; density is a setting not an operator

1.13.1 / 2013-09-15

  • added; boolean for % crop

1.13.0 / 2013-09-07

  • added; morph more than two images (overra)

1.12.2 / 2013-08-29

  • fixed; fallback to through in node 0.8

1.12.1 / 2013-08-29 (unpublished)

  • refactor; replace through with stream.PassThrough

1.12.0 / 2013-08-27

  • added; diff image output file (chenglou)

1.11.1 / 2013-08-17

  • added; proto.selectFrame(#)
  • fixed; getters should not ignore frame selection

1.11.0 / 2013-07-23

  • added; optional formatting string for gm().identify(format, callback) (tornillo)
  • removed; error messages when gm/im binary is not installed

1.10.0 / 2013-06-27

  • refactor; use native -auto-orient for imagemagick

1.9.2 / 2013-06-12

  • refactor; move streamToBuffer to a separate module
  • fixed; .stream(format) without a callback

1.9.1 / 2013-05-07

  • fixed; gm().resize(width) always only resizes width
  • fixed; gm('img.gif').format() returns the format of the first frame

1.9.0 / 2013-04-21

  • added; node v0.10 support
  • removed; node < v0.8 support - Buffer.concat()
  • tests; all tests now run on Travis
  • added; gm().stream() returns a stream when no callback is present
  • added; gm().toBuffer(callback)
  • fixed; gm().size() only returns the size of the first frame of a GIF

1.8.2 / 2013-03-07

  • include source path in identify data #126 soupdiver

1.8.1 / 2012-12-21

  • Avoid losing already set arguments on identify #105 #113 #109 JNissi
  • tests; add autoOrient + thumb() test
  • tests; add test case for #113
  • tests; added test for #109
  • tests; add resize on buffer test

1.8.0 / 2012-12-14

  • added; geometry support to scale() #98
  • removed; incorrect/broken dissolve() method (never worked)
  • fixed; handle child_proc error when using Buffer input #109
  • fixed; use of Buffers with identify() #109
  • fixed; no longer include -size arg with resize() #98
  • fixed; remove -size arg from extent() #103
  • fixed; magnify support
  • fixed; autoOrient to work with all types of exif orientations dambalah #108
  • tests; npm test runs unit only (now compatible with travis)
  • tests; fix magnify test on imagemagick
  • tests; added for cmd line args

1.7.0 / 2012-12-06

  • added; gm.compare support
  • added; passing Buffers directly danmilon

1.6.1 / 2012-11-13

  • fixed regression; only pass additional params on error #96

1.6.0 / 2012-11-10

1.5.1 / 2012-10-02

  • fixed; passing multiple paths to append() #77

1.5.0 / 2012-09-15

  • fixed; callback scope
  • fixed; append() usage #77

1.4.2 / 2012-08-17

  • fixed; identify parsing for ImageMagick exif data (#58)
  • fixed; when in imageMagick mode, complain about missing imageMagick bcherry (#73)
  • added; tests

1.4.1 / 2012-07-31

  • fixed; scenes() args
  • fixed; accept the left-to-right arg of append()
  • added; _subCommand

v1.4 - 07/28/2012

  • added; adjoin() [Math-]
  • added; affine() [Math-]
  • added; append() [Math-]
  • added; authenticate() [Math-]
  • added; average() [Math-]
  • added; backdrop() [Math-]
  • added; blackThreshold() [Math-]
  • added; bluePrimary() [Math-]
  • added; border() [Math-]
  • added; borderColor() [Math-]
  • added; box() [Math-]
  • added; channel() [Math-]
  • added; clip() [Math-]
  • added; coalesce() [Math-]
  • added; colorMap() [Math-]
  • added; compose() [Math-]
  • added; compress() [Math-]
  • added; convolve() [Math-]
  • added; createDirectories() [Math-]
  • added; deconstruct() [Math-]
  • added; delay() [Math-]
  • added; define() [Math-]
  • added; displace() [Math-]
  • added; display() [Math-]
  • added; dispose() [Math-]
  • added; disolve() [Math-]
  • added; encoding() [Math-]
  • added; endian() [Math-]
  • added; file() [Math-]
  • added; flatten() [Math-]
  • added; foreground() [Math-]
  • added; frame() [Math-]
  • added; fuzz() [Math-]
  • added; gaussian() [Math-]
  • added; geometry() [Math-]
  • added; greenPrimary() [Math-]
  • added; highlightColor() [Math-]
  • added; highlightStyle() [Math-]
  • added; iconGeometry() [Math-]
  • added; intent() [Math-]
  • added; lat() [Math-]
  • added; level() [Math-]
  • added; list() [Math-]
  • added; log() [Math-]
  • added; map() [Math-]
  • added; matte() [Math-]
  • added; matteColor() [Math-]
  • added; mask() [Math-]
  • added; maximumError() [Math-]
  • added; mode() [Math-]
  • added; monitor() [Math-]
  • added; mosaic() [Math-]
  • added; motionBlur() [Math-]
  • added; name() [Math-]
  • added; noop() [Math-]
  • added; normalize() [Math-]
  • added; opaque() [Math-]
  • added; operator() [Math-]
  • added; orderedDither() [Math-]
  • added; outputDirectory() [Math-]
  • added; page() [Math-]
  • added; pause() [Math-]
  • added; pen() [Math-]
  • added; ping() [Math-]
  • added; pointSize() [Math-]
  • added; preview() [Math-]
  • added; process() [Math-]
  • added; profile() [Math-]
  • added; progress() [Math-]
  • added; rawSize() [Math-]
  • added; randomThreshold() [Math-]
  • added; recolor() [Math-]
  • added; redPrimary() [Math-]
  • added; remote() [Math-]
  • added; render() [Math-]
  • added; repage() [Math-]
  • added; sample() [Math-]
  • added; samplingFactor() [Math-]
  • added; scene() [Math-]
  • added; scenes() [Math-]
  • added; screen() [Math-]
  • added; segment() [Math-]
  • added; set() [Math-]
  • added; shade() [Math-]
  • added; shadow() [Math-]
  • added; sharedMemory() [Math-]
  • added; shave() [Math-]
  • added; shear() [Math-]
  • added; silent() [Math-]
  • added; snaps() [Math-]
  • added; stagano() [Math-]
  • added; stereo() [Math-]
  • added; textFont() [Math-]
  • added; texture() [Math-]
  • added; threshold() [Math-]
  • added; tile() [Math-]
  • added; transform() [Math-]
  • added; transparent() [Math-]
  • added; treeDepth() [Math-]
  • added; update() [Math-]
  • added; units() [Math-]
  • added; unsharp() [Math-]
  • added; usePixmap() [Math-]
  • added; view() [Math-]
  • added; virtualPixel() [Math-]
  • added; visual() [Math-]
  • added; watermark() [Math-]
  • added; wave() [Math-]
  • added; whitePoint() [Math-]
  • added; whiteThreshold() [Math-]
  • added; window() [Math-]
  • added; windowGroup() [Math-]

v1.3.2 - 06/22/2012

  • added; node >= 0.7/0.8 compat

v1.3.1 - 06/06/2012

  • fixed; thumb() alignment and cropping [thomaschaaf]
  • added; hint when graphicsmagick is not installed (#62)
  • fixed; minify() (#59)

v1.3.0 - 04/11/2012

  • added; flatten support [jwarchol]
  • added; background support [jwarchol]
  • fixed; identify parser error [chriso]

v1.2.0 - 03/30/2012

  • added; extent and gravity support [jwarchol]

v1.1.0 - 03/15/2012

  • added; filter() support [travisbeck]
  • added; density() [travisbeck]
  • fixed; permit either width or height in resize [dambalah]
  • updated; docs

v1.0.5 - 02/15/2012

  • added; strip() support [Math-]
  • added; interlace() support [Math-]
  • added; setFormat() support [Math-]
  • fixed; regexps for image types [Math-]

v1.0.4 - 02/09/2012

  • expose utils

v1.0.3 - 01/27/2012

  • removed; console.log

v1.0.2 - 01/24/2012

  • added; debugging info on parser errors
  • fixed; exports.version

v1.0.1 - 01/12/2012

  • fixed; use of reserved keyword super for node v0.5+

v1.0.0 - 01/12/2012

  • added; autoOrient support [kainosnoema] (#21)
  • added; orientation support [kainosnoema] (#21)
  • fixed; identify parser now properly JSON formats all data output by gm identify such as IPTC, GPS, Make, etc (#20)
  • added; support for running as imagemagick (#23, #29)
  • added; subclassing support; useful for setting default constructor options like one constructor for ImageMagick, the other for GM
  • added; more tests
  • changed; remove redundant orientation, resolution, and filesize from this.data in indentify(). Use their uppercase equivalents.

v0.6.0 - 12/14/2011

  • added; stream support [kainosnoema] (#22)

v0.5.0 - 07/07/2011

  • added; gm#trim() support [lepokle]
  • added; gm#inputIs() support
  • fixed; 'geometry does not contain image' error: gh-17

v0.4.3 - 05/17/2011

  • added; bunch of tests
  • fixed; polygon, polyline, bezier drawing bug

v0.4.2 - 05/10/2011

  • added; resize options support

v0.4.1 - 04/28/2011

  • shell args are now escaped (thanks @visionmedia)
  • added; gm.in()
  • added; gm.out()
  • various refactoring

v0.4.0 - 9/21/2010

  • removed deprecated new method
  • added drawing docs

v0.3.2 - 9/06/2010

  • new images are now created using same gm() constructor

v0.3.1 - 9/06/2010

  • can now create images from scratch
  • add type method

v0.3.0 - 8/26/2010

  • add drawing api

v0.2.2 - 8/22/2010

  • add quality option to thumb()
  • add teropa to contributors
  • added support for colorspace()

v0.2.1 - 7/31/2010

  • fixed naming conflict. depth() manipulation method renamed bitdepth()
  • added better docs

v0.2.0 - 7/29/2010

new methods

  • swirl
  • spread
  • solarize
  • sharpen
  • roll
  • sepia
  • region
  • raise
  • lower
  • paint
  • noise
  • negative
  • morph
  • median
  • antialias
  • limit
  • label
  • implode
  • gamma
  • enhance
  • equalize
  • emboss
  • edge
  • dither
  • monochrome
  • despeckle
  • depth
  • cycle
  • contrast
  • comment
  • colors

added more default args to several methods added more examples

v0.1.2 - 7/28/2010

  • refactor project into separate modules

v0.1.1 - 7/27/2010

  • add modulate method
  • add colorize method
  • add charcoal method
  • add chop method
  • bug fix in write without a callback

v0.1.0 - 6/27/2010

  • no longer supporting mogrify
  • add image data getter methods

    • size
    • format
    • color
    • res
    • depth
    • filesize
    • identify
  • add new convert methods

    • scale
    • resample
    • rotate
    • flip
    • flop
    • crop
    • magnify
    • minify
    • quality
    • blur
    • thumb

v0.0.1 - 6/11/2010

Initial release