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