UNPKG

23.8 kBMarkdownView Raw
1
2THIS REPOSITORY NEEDS A MAINTAINER. IF YOU'RE INTERESTED IN MAINTAING THIS MODULE, PLEASE LET US KNOW!
3
4# gm v1.15.0 [![Build Status](https://travis-ci.org/aheckmann/gm.png?branch=master)](https://travis-ci.org/aheckmann/gm)
5
6GraphicsMagick and ImageMagick for node
7
8## Getting started
9First download and install [GraphicsMagick](http://www.graphicsmagick.org/) or [ImageMagick](http://www.imagemagick.org/). In Mac OS X, you can simply use [Homebrew](http://mxcl.github.io/homebrew/) and do:
10
11 brew install imagemagick
12 brew install graphicsmagick
13
14If you want WebP support with ImageMagick, you must add the WebP option:
15
16 brew install imagemagick --with-webp
17
18then either use npm:
19
20 npm install gm
21
22or clone the repo:
23
24 git clone git://github.com/aheckmann/gm.git
25
26
27## Basic Usage
28
29```js
30var fs = require('fs')
31 , gm = require('./gm');
32
33// resize and remove EXIF profile data
34gm('/path/to/my/img.jpg')
35.resize(240, 240)
36.noProfile()
37.write('/path/to/resize.png', function (err) {
38 if (!err) console.log('done');
39});
40
41// obtain the size of an image
42gm('/path/to/my/img.jpg')
43.size(function (err, size) {
44 if (!err)
45 console.log(size.width > size.height ? 'wider' : 'taller than you');
46});
47
48// output all available image properties
49gm('/path/to/img.png')
50.identify(function (err, data) {
51 if (!err) console.log(data)
52});
53
54// pull out the first frame of an animated gif and save as png
55gm('/path/to/animated.gif[0]')
56.write('/path/to/firstframe.png', function (err) {
57 if (err) console.log('aaw, shucks');
58});
59
60// auto-orient an image
61gm('/path/to/img.jpg')
62.autoOrient()
63.write('/path/to/oriented.jpg', function (err) {
64 if (err) ...
65})
66
67// crazytown
68gm('/path/to/my/img.jpg')
69.flip()
70.magnify()
71.rotate('green', 45)
72.blur(7, 3)
73.crop(300, 300, 150, 130)
74.edge(3)
75.write('/path/to/crazy.jpg', function (err) {
76 if (!err) console.log('crazytown has arrived');
77})
78
79// annotate an image
80gm('/path/to/my/img.jpg')
81.stroke("#ffffff")
82.drawCircle(10, 10, 20, 10)
83.font("Helvetica.ttf", 12)
84.drawText(30, 20, "GMagick!")
85.write("/path/to/drawing.png", function (err) {
86 if (!err) console.log('done');
87});
88
89// creating an image
90gm(200, 400, "#ddff99f3")
91.drawText(10, 50, "from scratch")
92.write("/path/to/brandNewImg.jpg", function (err) {
93 // ...
94});
95```
96
97## Streams
98
99```js
100// passing a stream
101var readStream = fs.createReadStream('/path/to/my/img.jpg');
102gm(readStream, 'img.jpg')
103.write('/path/to/reformat.png', function (err) {
104 if (!err) console.log('done');
105});
106
107// can also stream output to a ReadableStream
108// (can be piped to a local file or remote server)
109gm('/path/to/my/img.jpg')
110.resize('200', '200')
111.stream(function (err, stdout, stderr) {
112 var writeStream = fs.createWriteStream('/path/to/my/resized.jpg');
113 stdout.pipe(writeStream);
114});
115
116// without a callback, .stream() returns a stream
117// this is just a convenience wrapper for above.
118var writeStream = fs.createWriteStream('/path/to/my/resized.jpg');
119gm('/path/to/my/img.jpg')
120.resize('200', '200')
121.stream()
122.pipe(writeStream);
123
124// pass a format or filename to stream() and
125// gm will provide image data in that format
126gm('/path/to/my/img.jpg')
127.stream('png', function (err, stdout, stderr) {
128 var writeStream = fs.createWriteStream('/path/to/my/reformated.png');
129 stdout.pipe(writeStream);
130});
131
132// or without the callback
133var writeStream = fs.createWriteStream('/path/to/my/reformated.png');
134gm('/path/to/my/img.jpg')
135.stream('png')
136.pipe(writeStream);
137
138// combine the two for true streaming image processing
139var readStream = fs.createReadStream('/path/to/my/img.jpg');
140gm(readStream, 'img.jpg')
141.resize('200', '200')
142.stream(function (err, stdout, stderr) {
143 var writeStream = fs.createWriteStream('/path/to/my/resized.jpg');
144 stdout.pipe(writeStream);
145});
146
147// GOTCHA:
148// when working with input streams and any 'identify'
149// operation (size, format, etc), you must pass "{bufferStream: true}" if
150// you also need to convert (write() or stream()) the image afterwards
151// NOTE: this buffers the readStream in memory!
152var readStream = fs.createReadStream('/path/to/my/img.jpg');
153gm(readStream, 'img.jpg')
154.size({bufferStream: true}, function(err, size) {
155 this.resize(size.width / 2, size.height / 2)
156 this.write('/path/to/resized.jpg', function (err) {
157 if (!err) console.log('done');
158 });
159});
160
161```
162
163## Buffers
164
165```js
166// A buffer can be passed instead of a filepath as well
167var buf = require('fs').readFileSync('/path/to/image.jpg');
168
169gm(buf, 'image.jpg')
170.noise('laplacian')
171.write('/path/to/out.jpg', function (err) {
172 if (err) return handle(err);
173 console.log('Created an image from a Buffer!');
174});
175
176// A buffer can also be returned instead of a stream
177gm('img.jpg')
178.resize(100, 100)
179.toBuffer(function (err, buffer) {
180 if (err) return handle(err);
181 console.log('done!');
182})
183```
184
185## Custom Arguments
186
187If `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.
188
189- `gm().command()` - Custom command such as `identify` or `convert`
190- `gm().in()` - Custom input arguments
191- `gm().out()` - Custom output arguments
192
193The command will be formatted in the following order:
194
1951. `command` - ie `convert`
1962. `in` - the input arguments
1973. `source` - stdin or an image file
1984. `out` - the output arguments
1995. `output` - stdout or the image file to write to
200
201For example, suppose you want the following command:
202
203```bash
204gm "convert" "label:Offline" "PNG:-"
205```
206
207However, using `gm().label()` may not work as intended for you:
208
209```js
210gm()
211.label('Offline')
212.stream();
213```
214
215would yield:
216
217```bash
218gm "convert" "-label" "\"Offline\"" "PNG:-"
219```
220
221Instead, you can use `gm().out()`:
222
223```js
224gm()
225.out('label:Offline')
226.stream();
227```
228
229which correctly yields:
230
231```bash
232gm "convert" "label:Offline" "PNG:-"
233```
234
235### Custom Identify Format String
236
237When identifying an image, you may want to use a custom formatting string instead of using `-verbose`, which is quite slow.
238You can use your own [formatting string](http://www.imagemagick.org/script/escape.php) when using `gm().identify(format, callback)`.
239For example,
240
241```js
242gm('img.png').format(function (err, format) {
243
244})
245
246// is equivalent to
247
248gm('img.png').identify('%m', function (err, format) {
249
250})
251```
252
253since `%m` is the format option for getting the image file format.
254
255## Platform differences
256
257Please document and refer to any [platform or ImageMagick/GraphicsMagick issues/differences here](https://github.com/aheckmann/gm/wiki/GraphicsMagick-and-ImageMagick-versions).
258
259## Examples:
260
261 Check out the [examples](http://github.com/aheckmann/gm/tree/master/examples/) directory to play around.
262 Also take a look at the [extending gm](http://wiki.github.com/aheckmann/gm/extending-gm)
263 page to see how to customize gm to your own needs.
264
265## Constructor:
266
267 There are a few ways you can use the `gm` image constructor.
268
269 - 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.
270 - 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.
271 - 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](http://github.com/aheckmann/gm/blob/master/examples/new.js) for an example.
272
273## Methods
274
275 - getters
276 - [size](http://aheckmann.github.com/gm/docs.html#getters) - returns the size (WxH) of the image
277 - [orientation](http://aheckmann.github.com/gm/docs.html#orientation) - returns the EXIF orientation of the image
278 - [format](http://aheckmann.github.com/gm/docs.html#getters) - returns the image format (gif, jpeg, png, etc)
279 - [depth](http://aheckmann.github.com/gm/docs.html#getters) - returns the image color depth
280 - [color](http://aheckmann.github.com/gm/docs.html#getters) - returns the number of colors
281 - [res](http://aheckmann.github.com/gm/docs.html#getters) - returns the image resolution
282 - [filesize](http://aheckmann.github.com/gm/docs.html#getters) - returns image filesize
283 - [identify](http://aheckmann.github.com/gm/docs.html#getters) - returns all image data available. Takes an optional format string.
284
285 - manipulation
286 - [adjoin](http://aheckmann.github.com/gm/docs.html#adjoin)
287 - [affine](http://aheckmann.github.com/gm/docs.html#affine)
288 - [antialias](http://aheckmann.github.com/gm/docs.html#antialias)
289 - [append](http://aheckmann.github.com/gm/docs.html#append)
290 - [authenticate](http://aheckmann.github.com/gm/docs.html#authenticate)
291 - [autoOrient](http://aheckmann.github.com/gm/docs.html#autoOrient)
292 - [average](http://aheckmann.github.com/gm/docs.html#average)
293 - [backdrop](http://aheckmann.github.com/gm/docs.html#backdrop)
294 - [bitdepth](http://aheckmann.github.com/gm/docs.html#bitdepth)
295 - [blackThreshold](http://aheckmann.github.com/gm/docs.html#blackThreshold)
296 - [bluePrimary](http://aheckmann.github.com/gm/docs.html#bluePrimary)
297 - [blur](http://aheckmann.github.com/gm/docs.html#blur)
298 - [border](http://aheckmann.github.com/gm/docs.html#border)
299 - [borderColor](http://aheckmann.github.com/gm/docs.html#borderColor)
300 - [box](http://aheckmann.github.com/gm/docs.html#box)
301 - [channel](http://aheckmann.github.com/gm/docs.html#channel)
302 - [charcoal](http://aheckmann.github.com/gm/docs.html#charcoal)
303 - [chop](http://aheckmann.github.com/gm/docs.html#chop)
304 - [clip](http://aheckmann.github.com/gm/docs.html#clip)
305 - [coalesce](http://aheckmann.github.com/gm/docs.html#coalesce)
306 - [colors](http://aheckmann.github.com/gm/docs.html#colors)
307 - [colorize](http://aheckmann.github.com/gm/docs.html#colorize)
308 - [colorMap](http://aheckmann.github.com/gm/docs.html#colorMap)
309 - [colorspace](http://aheckmann.github.com/gm/docs.html#colorspace)
310 - [comment](http://aheckmann.github.com/gm/docs.html#comment)
311 - [compose](http://aheckmann.github.com/gm/docs.html#compose)
312 - [compress](http://aheckmann.github.com/gm/docs.html#compress)
313 - [contrast](http://aheckmann.github.com/gm/docs.html#contrast)
314 - [convolve](http://aheckmann.github.com/gm/docs.html#convolve)
315 - [createDirectories](http://aheckmann.github.com/gm/docs.html#createDirectories)
316 - [crop](http://aheckmann.github.com/gm/docs.html#crop)
317 - [cycle](http://aheckmann.github.com/gm/docs.html#cycle)
318 - [deconstruct](http://aheckmann.github.com/gm/docs.html#deconstruct)
319 - [delay](http://aheckmann.github.com/gm/docs.html#delay)
320 - [define](http://aheckmann.github.com/gm/docs.html#define)
321 - [density](http://aheckmann.github.com/gm/docs.html#density)
322 - [despeckle](http://aheckmann.github.com/gm/docs.html#despeckle)
323 - [dither](http://aheckmann.github.com/gm/docs.html#dither)
324 - [displace](http://aheckmann.github.com/gm/docs.html#dither)
325 - [display](http://aheckmann.github.com/gm/docs.html#display)
326 - [dispose](http://aheckmann.github.com/gm/docs.html#dispose)
327 - [edge](http://aheckmann.github.com/gm/docs.html#edge)
328 - [emboss](http://aheckmann.github.com/gm/docs.html#emboss)
329 - [encoding](http://aheckmann.github.com/gm/docs.html#encoding)
330 - [enhance](http://aheckmann.github.com/gm/docs.html#enhance)
331 - [endian](http://aheckmann.github.com/gm/docs.html#endian)
332 - [equalize](http://aheckmann.github.com/gm/docs.html#equalize)
333 - [extent](http://aheckmann.github.com/gm/docs.html#extent)
334 - [file](http://aheckmann.github.com/gm/docs.html#file)
335 - [filter](http://aheckmann.github.com/gm/docs.html#filter)
336 - [flatten](http://aheckmann.github.com/gm/docs.html#flatten)
337 - [flip](http://aheckmann.github.com/gm/docs.html#flip)
338 - [flop](http://aheckmann.github.com/gm/docs.html#flop)
339 - [foreground](http://aheckmann.github.com/gm/docs.html#foreground)
340 - [frame](http://aheckmann.github.com/gm/docs.html#frame)
341 - [fuzz](http://aheckmann.github.com/gm/docs.html#fuzz)
342 - [gamma](http://aheckmann.github.com/gm/docs.html#gamma)
343 - [gaussian](http://aheckmann.github.com/gm/docs.html#gaussian)
344 - [geometry](http://aheckmann.github.com/gm/docs.html#geometry)
345 - [gravity](http://aheckmann.github.com/gm/docs.html#gravity)
346 - [greenPrimary](http://aheckmann.github.com/gm/docs.html#greenPrimary)
347 - [highlightColor](http://aheckmann.github.com/gm/docs.html#highlightColor)
348 - [highlightStyle](http://aheckmann.github.com/gm/docs.html#highlightStyle)
349 - [iconGeometry](http://aheckmann.github.com/gm/docs.html#iconGeometry)
350 - [implode](http://aheckmann.github.com/gm/docs.html#implode)
351 - [intent](http://aheckmann.github.com/gm/docs.html#intent)
352 - [interlace](http://aheckmann.github.com/gm/docs.html#interlace)
353 - [label](http://aheckmann.github.com/gm/docs.html#label)
354 - [lat](http://aheckmann.github.com/gm/docs.html#lat)
355 - [level](http://aheckmann.github.com/gm/docs.html#level)
356 - [list](http://aheckmann.github.com/gm/docs.html#list)
357 - [limit](http://aheckmann.github.com/gm/docs.html#limit)
358 - [log](http://aheckmann.github.com/gm/docs.html#log)
359 - [loop](http://aheckmann.github.com/gm/docs.html#loop)
360 - [lower](http://aheckmann.github.com/gm/docs.html#lower)
361 - [magnify](http://aheckmann.github.com/gm/docs.html#magnify)
362 - [map](http://aheckmann.github.com/gm/docs.html#map)
363 - [matte](http://aheckmann.github.com/gm/docs.html#matte)
364 - [matteColor](http://aheckmann.github.com/gm/docs.html#matteColor)
365 - [mask](http://aheckmann.github.com/gm/docs.html#mask)
366 - [maximumError](http://aheckmann.github.com/gm/docs.html#maximumError)
367 - [median](http://aheckmann.github.com/gm/docs.html#median)
368 - [minify](http://aheckmann.github.com/gm/docs.html#minify)
369 - [mode](http://aheckmann.github.com/gm/docs.html#mode)
370 - [modulate](http://aheckmann.github.com/gm/docs.html#modulate)
371 - [monitor](http://aheckmann.github.com/gm/docs.html#monitor)
372 - [monochrome](http://aheckmann.github.com/gm/docs.html#monochrome)
373 - [morph](http://aheckmann.github.com/gm/docs.html#morph)
374 - [mosaic](http://aheckmann.github.com/gm/docs.html#mosaic)
375 - [motionBlur](http://aheckmann.github.com/gm/docs.html#motionBlur)
376 - [name](http://aheckmann.github.com/gm/docs.html#name)
377 - [negative](http://aheckmann.github.com/gm/docs.html#negative)
378 - [noise](http://aheckmann.github.com/gm/docs.html#noise)
379 - [noop](http://aheckmann.github.com/gm/docs.html#noop)
380 - [normalize](http://aheckmann.github.com/gm/docs.html#normalize)
381 - [noProfile](http://aheckmann.github.com/gm/docs.html#profile)
382 - [opaque](http://aheckmann.github.com/gm/docs.html#opaque)
383 - [operator](http://aheckmann.github.com/gm/docs.html#operator)
384 - [orderedDither](http://aheckmann.github.com/gm/docs.html#orderedDither)
385 - [outputDirectory](http://aheckmann.github.com/gm/docs.html#outputDirectory)
386 - [paint](http://aheckmann.github.com/gm/docs.html#paint)
387 - [page](http://aheckmann.github.com/gm/docs.html#page)
388 - [pause](http://aheckmann.github.com/gm/docs.html#pause)
389 - [pen](http://aheckmann.github.com/gm/docs.html#pen)
390 - [ping](http://aheckmann.github.com/gm/docs.html#ping)
391 - [pointSize](http://aheckmann.github.com/gm/docs.html#pointSize)
392 - [preview](http://aheckmann.github.com/gm/docs.html#preview)
393 - [process](http://aheckmann.github.com/gm/docs.html#process)
394 - [profile](http://aheckmann.github.com/gm/docs.html#profile)
395 - [progress](http://aheckmann.github.com/gm/docs.html#progress)
396 - [quality](http://aheckmann.github.com/gm/docs.html#quality)
397 - [raise](http://aheckmann.github.com/gm/docs.html#raise)
398 - [rawSize](http://aheckmann.github.com/gm/docs.html#rawSize)
399 - [randomThreshold](http://aheckmann.github.com/gm/docs.html#randomThreshold)
400 - [recolor](http://aheckmann.github.com/gm/docs.html#recolor)
401 - [redPrimary](http://aheckmann.github.com/gm/docs.html#redPrimary)
402 - [region](http://aheckmann.github.com/gm/docs.html#region)
403 - [remote](http://aheckmann.github.com/gm/docs.html#remote)
404 - [render](http://aheckmann.github.com/gm/docs.html#render)
405 - [repage](http://aheckmann.github.com/gm/docs.html#repage)
406 - [resample](http://aheckmann.github.com/gm/docs.html#resample)
407 - [resize](http://aheckmann.github.com/gm/docs.html#resize)
408 - [roll](http://aheckmann.github.com/gm/docs.html#roll)
409 - [rotate](http://aheckmann.github.com/gm/docs.html#rotate)
410 - [sample](http://aheckmann.github.com/gm/docs.html#sample)
411 - [samplingFactor](http://aheckmann.github.com/gm/docs.html#samplingFactor)
412 - [scale](http://aheckmann.github.com/gm/docs.html#scale)
413 - [scene](http://aheckmann.github.com/gm/docs.html#scene)
414 - [scenes](http://aheckmann.github.com/gm/docs.html#scenes)
415 - [screen](http://aheckmann.github.com/gm/docs.html#screen)
416 - [segment](http://aheckmann.github.com/gm/docs.html#segment)
417 - [sepia](http://aheckmann.github.com/gm/docs.html#sepia)
418 - [set](http://aheckmann.github.com/gm/docs.html#set)
419 - [setFormat](http://aheckmann.github.com/gm/docs.html#setformat)
420 - [shade](http://aheckmann.github.com/gm/docs.html#shade)
421 - [shadow](http://aheckmann.github.com/gm/docs.html#shadow)
422 - [sharedMemory](http://aheckmann.github.com/gm/docs.html#sharedMemory)
423 - [sharpen](http://aheckmann.github.com/gm/docs.html#sharpen)
424 - [shave](http://aheckmann.github.com/gm/docs.html#shave)
425 - [shear](http://aheckmann.github.com/gm/docs.html#shear)
426 - [silent](http://aheckmann.github.com/gm/docs.html#silent)
427 - [solarize](http://aheckmann.github.com/gm/docs.html#solarize)
428 - [snaps](http://aheckmann.github.com/gm/docs.html#snaps)
429 - [stegano](http://aheckmann.github.com/gm/docs.html#stegano)
430 - [stereo](http://aheckmann.github.com/gm/docs.html#stereo)
431 - [strip](http://aheckmann.github.com/gm/docs.html#strip) _imagemagick only_
432 - [spread](http://aheckmann.github.com/gm/docs.html#spread)
433 - [swirl](http://aheckmann.github.com/gm/docs.html#swirl)
434 - [textFont](http://aheckmann.github.com/gm/docs.html#textFont)
435 - [texture](http://aheckmann.github.com/gm/docs.html#texture)
436 - [threshold](http://aheckmann.github.com/gm/docs.html#threshold)
437 - [thumb](http://aheckmann.github.com/gm/docs.html#thumb)
438 - [tile](http://aheckmann.github.com/gm/docs.html#tile)
439 - [transform](http://aheckmann.github.com/gm/docs.html#transform)
440 - [transparent](http://aheckmann.github.com/gm/docs.html#transparent)
441 - [treeDepth](http://aheckmann.github.com/gm/docs.html#treeDepth)
442 - [trim](http://aheckmann.github.com/gm/docs.html#trim)
443 - [type](http://aheckmann.github.com/gm/docs.html#type)
444 - [update](http://aheckmann.github.com/gm/docs.html#update)
445 - [units](http://aheckmann.github.com/gm/docs.html#units)
446 - [unsharp](http://aheckmann.github.com/gm/docs.html#unsharp)
447 - [usePixmap](http://aheckmann.github.com/gm/docs.html#usePixmap)
448 - [view](http://aheckmann.github.com/gm/docs.html#view)
449 - [virtualPixel](http://aheckmann.github.com/gm/docs.html#virtualPixel)
450 - [visual](http://aheckmann.github.com/gm/docs.html#visual)
451 - [watermark](http://aheckmann.github.com/gm/docs.html#watermark)
452 - [wave](http://aheckmann.github.com/gm/docs.html#wave)
453 - [whitePoint](http://aheckmann.github.com/gm/docs.html#whitePoint)
454 - [whiteThreshold](http://aheckmann.github.com/gm/docs.html#whiteThreshold)
455 - [window](http://aheckmann.github.com/gm/docs.html#window)
456 - [windowGroup](http://aheckmann.github.com/gm/docs.html#windowGroup)
457
458 - drawing primitives
459 - [draw](http://aheckmann.github.com/gm/docs.html#draw)
460 - [drawArc](http://aheckmann.github.com/gm/docs.html#drawArc)
461 - [drawBezier](http://aheckmann.github.com/gm/docs.html#drawBezier)
462 - [drawCircle](http://aheckmann.github.com/gm/docs.html#drawCircle)
463 - [drawEllipse](http://aheckmann.github.com/gm/docs.html#drawEllipse)
464 - [drawLine](http://aheckmann.github.com/gm/docs.html#drawLine)
465 - [drawPoint](http://aheckmann.github.com/gm/docs.html#drawPoint)
466 - [drawPolygon](http://aheckmann.github.com/gm/docs.html#drawPolygon)
467 - [drawPolyline](http://aheckmann.github.com/gm/docs.html#drawPolyline)
468 - [drawRectangle](http://aheckmann.github.com/gm/docs.html#drawRectangle)
469 - [drawText](http://aheckmann.github.com/gm/docs.html#drawText)
470 - [fill](http://aheckmann.github.com/gm/docs.html#fill)
471 - [font](http://aheckmann.github.com/gm/docs.html#font)
472 - [fontSize](http://aheckmann.github.com/gm/docs.html#fontSize)
473 - [stroke](http://aheckmann.github.com/gm/docs.html#stroke)
474 - [strokeWidth](http://aheckmann.github.com/gm/docs.html#strokeWidth)
475 - [setDraw](http://aheckmann.github.com/gm/docs.html#setDraw)
476
477 - image output
478 - **write** - writes the processed image data to the specified filename
479 - **stream** - provides a `ReadableStream` with the processed image data
480 - **toBuffer** - returns the image as a `Buffer` instead of a stream
481
482##compare
483
484Graphicsmagicks `compare` command is exposed through `gm.compare()`. This allows us to determine if two images can be considered "equal".
485
486Currently `gm.compare` only accepts file paths.
487
488 gm.compare(path1, path2 [, options], callback)
489
490```js
491gm.compare('/path/to/image1.jpg', '/path/to/another.png', function (err, isEqual, equality, raw) {
492 if (err) return handle(err);
493
494 // if the images were considered equal, `isEqual` will be true, otherwise, false.
495 console.log('The images were equal: %s', isEqual);
496
497 // to see the total equality returned by graphicsmagick we can inspect the `equality` argument.
498 console.log('Actual equality: %d', equality);
499
500 // inspect the raw output
501 console.log(raw)
502})
503```
504
505You may wish to pass a custom tolerance threshold to increase or decrease the default level of `0.4`.
506
507
508```js
509gm.compare('/path/to/image1.jpg', '/path/to/another.png', 1.2, function (err, isEqual) {
510 ...
511})
512```
513
514To output a diff image, pass a configuration object to define the diff options and tolerance.
515
516
517```js
518var options = {
519 file: '/path/to/diff.png',
520 highlightColor: 'yellow',
521 tolerance: 0.02
522}
523gm.compare('/path/to/image1.jpg', '/path/to/another.png', options, function (err, isEqual, equality, raw) {
524 ...
525})
526```
527
528## Contributors
529[https://github.com/aheckmann/gm/contributors](https://github.com/aheckmann/gm/contributors)
530
531## Inspiration
532http://github.com/quiiver/magickal-node
533
534## Plugins
535[https://github.com/aheckmann/gm/wiki](https://github.com/aheckmann/gm/wiki)
536
537## License
538
539(The MIT License)
540
541Copyright (c) 2010 [Aaron Heckmann](aaron.heckmann+github@gmail.com)
542
543Permission is hereby granted, free of charge, to any person obtaining
544a copy of this software and associated documentation files (the
545'Software'), to deal in the Software without restriction, including
546without limitation the rights to use, copy, modify, merge, publish,
547distribute, sublicense, and/or sell copies of the Software, and to
548permit persons to whom the Software is furnished to do so, subject to
549the following conditions:
550
551The above copyright notice and this permission notice shall be
552included in all copies or substantial portions of the Software.
553
554THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
555EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
556MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
557IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
558CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
559TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
560SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.