Showing preview only (265K chars total). Download the full file or copy to clipboard to get everything.
Repository: aheckmann/gm
Branch: master
Commit: 6e43846ef7e3
Files: 206
Total size: 229.9 KB
Directory structure:
gitextract_x_d7l3ph/
├── .github/
│ └── workflows/
│ └── node.js.yml
├── .gitignore
├── .npmignore
├── History.md
├── README.md
├── examples/
│ ├── append.js
│ ├── background.js
│ ├── bitdepth.js
│ ├── blur.js
│ ├── changeFormat.js
│ ├── charcoal.js
│ ├── chop.js
│ ├── colorize.js
│ ├── colors.js
│ ├── comment.js
│ ├── compare.js
│ ├── contrast.js
│ ├── crop.js
│ ├── cycle.js
│ ├── despeckle.js
│ ├── dither.js
│ ├── drawing.js
│ ├── edge.js
│ ├── emboss.js
│ ├── enhance.js
│ ├── equalize.js
│ ├── extent.js
│ ├── flatten.js
│ ├── flip.js
│ ├── flop.js
│ ├── gamma.js
│ ├── getters.js
│ ├── gravity.js
│ ├── implode.js
│ ├── label.js
│ ├── limit.js
│ ├── lower.js
│ ├── magnify.js
│ ├── median.js
│ ├── minify.js
│ ├── modulate.js
│ ├── monochrome.js
│ ├── morph.js
│ ├── negative.js
│ ├── new.js
│ ├── noise1.js
│ ├── noise2.js
│ ├── paint.js
│ ├── quality.js
│ ├── raise.js
│ ├── region.js
│ ├── resample.js
│ ├── resize.js
│ ├── roll.js
│ ├── rotate.js
│ ├── scale.js
│ ├── sepia.js
│ ├── sharpen.js
│ ├── size.js
│ ├── solarize.js
│ ├── source_buffer.js
│ ├── spread.js
│ ├── swirl.js
│ ├── thumb.js
│ ├── thumbExact.js
│ └── thumbnail.js
├── index.js
├── lib/
│ ├── args.js
│ ├── command.js
│ ├── compare.js
│ ├── composite.js
│ ├── convenience/
│ │ ├── autoOrient.js
│ │ ├── morph.js
│ │ ├── sepia.js
│ │ └── thumb.js
│ ├── convenience.js
│ ├── drawing.js
│ ├── getters.js
│ ├── montage.js
│ ├── options.js
│ └── utils.js
├── package.json
└── test/
├── 109.js
├── 118.js
├── 393.js
├── 417.js
├── 422.js
├── 429.js
├── 68.js
├── 70.js
├── 78.js
├── alpha.js
├── append.js
├── arc.js
├── autoOrient.js
├── autoOrientAll.js
├── autoOrientAndThumb.js
├── autoOrientStream.js
├── background.js
├── bezier.js
├── bitdepth.js
├── blur.js
├── changeFormat.js
├── charcoal.js
├── chop.js
├── circle.js
├── colorize.js
├── colors.js
├── comment.js
├── compare.js
├── composite.js
├── contrast.js
├── crop.js
├── cycle.js
├── densityGm.js
├── despeckle.js
├── dispose.js
├── dither.js
├── edge.js
├── ellipse.js
├── emboss.js
├── enhance.js
├── equalize.js
├── extent.js
├── flatten.js
├── flip.js
├── flop.js
├── fromBuffer.js
├── gamma.js
├── geometry.js
├── getterColor.js
├── getterDepth.js
├── getterFilesize.js
├── getterFormat.js
├── getterFormatGIF.js
├── getterIdentify.js
├── getterIptc.js
├── getterMultipleIptc.js
├── getterRes.js
├── getterSize.js
├── gh-17.js
├── gifFrame.js
├── gifFrameIdentify.js
├── gifFrameStream.js
├── gravity.js
├── implode.js
├── index.js
├── inputIs.js
├── interlace.js
├── label.js
├── limit.js
├── line.js
├── lower.js
├── magnify.js
├── median.js
├── minify.js
├── minifyIM.js
├── modulate.js
├── monochrome.js
├── montage.js
├── morph-more.js
├── morph.js
├── negative.js
├── new.js
├── newImage.js
├── noise1.js
├── noise2.js
├── options.js
├── paint.js
├── polygon.js
├── polyline.js
├── quality.js
├── raise.js
├── rectangle.js
├── region.js
├── repagePlus.js
├── resample.js
├── resize.js
├── resizeAndAutoOrientFromBuffer.js
├── resizeBuffer.js
├── resizeWrong.js
├── roll.js
├── rotate.js
├── scale.js
├── selectFrame.js
├── sepia.js
├── setFormat.js
├── sharpen.js
├── solarize.js
├── spread.js
├── streamIn.js
├── streamInGetter.js
├── streamInOut.js
├── streamOut.js
├── streamOutFormat.js
├── strip.js
├── subclass.js
├── swirl.js
├── text.js
├── thumb.js
├── thumbnail.js
├── timeout.js
├── toBuffer.js
├── toBufferFormat.js
├── utils.js
└── webp.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/node.js.yml
================================================
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ${{ matrix.os }}
env:
DEBUG: "gm*"
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
node-version: [14.x, 16.x, 18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: Install GraphicsMagic and Imagemagick on Ubuntu
if: contains(matrix.os, 'ubuntu')
run: sudo apt-get install -y imagemagick graphicsmagick
- name: Install GraphicsMagic and Imagemagick on Windows
if: contains(matrix.os, 'windows')
run: choco install -y imagemagick graphicsmagick
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm i
- name: Run tests on Windows
if: contains(matrix.os, 'windows')
shell: cmd
run: |
call refreshenv
npm test
- name: Run tests on Ubuntu
if: contains(matrix.os, 'ubuntu')
run: npm test
================================================
FILE: .gitignore
================================================
.DS_Store
node_modules
package-lock.json
examples/imgs/*
!examples/imgs/original.jpg
!examples/imgs/original.png
!examples/imgs/original.gif
!examples/imgs/originalSideways.jpg
!examples/imgs/morpher.jpg
!examples/imgs/photo.JPG
!examples/imgs/orientation/*\d.jpg
!examples/imgs/orientation/*.correct.jpg
*.sw*
.idea
================================================
FILE: .npmignore
================================================
test/
examples/
================================================
FILE: History.md
================================================
1.25.1 / 2025-02-24
* deps: bump cross-spawn [talyuk](https://github.com/talyuk)
1.25.0 / 2022-09-21
* fixed: windows support #846, #774, #594, #524, #528, #559, #652, #682 [piotr-cz](https://github.com/piotr-cz)
* docs; improvements from #821 [agokhale](https://github.com/agokhale)
* docs; improvements #801 [aarongarciah](https://github.com/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](https://github.com/emaniacs)
* fixed; error handling if gm is not installed #499 [aeo3](https://github.com/aeo3)
* fixed; highlightColor typo in compare #504 [DanielHudson](https://github.com/DanielHudson)
* docs; Fix typo #475 [rodrigoalviani](https://github.com/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](https://github.com/rwky)
1.21.0 / 2015-10-26 **contains security fix**
* fixed: gm.compare fails to escape arguments properly (Reported by Brendan Scarvell) [rwky](https://github.com/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](https://github.com/encima)
* changed: Refactored orientation getter to use faster identify call [lbeschastny](https://github.com/lbeschastny)
* added: resizeExact function [DanMMX](https://github.com/DanMMX)
* added: thumbExact function [DanMMX](https://github.com/DanMMX)
* added: Add format inference from filename for buffers/streams [adurrive](https://github.com/adurrive)
* fixed: Hex values when passed to compare aren't quoted automatically [DanMMX](https://github.com/DanMMX)
* fixed: identify returning last frame size instead of the larges on animated gifs [preynal](https://github.com/preynal)
* docs: Updated docs [laurilehmijoki](https://github.com/laurilehmijoki)
1.18.1 / 2015-05-18
* changed: Added io.js support [rwky](https://github.com/rwky)
1.18.0 / 2015-05-18
* changed: Removed support for node 0.8 and added support for 0.12 [rwky](https://github.com/rwky)
* changed: Listen to stdin error event for spawn errors [kapouer](https://github.com/kapouer)
* changed: Improved error handling when gm isn't installed [FreshXOpenSource](https://github.com/FreshXOpenSource)
* changed: Allow append method to use an array of arguments [emohacker](https://github.com/emohacker)
* changed: appPath option now specifies full path to gm binary John Borkowski
* changed: Ignore warning messages for identify [asrail](https://github.com/asrail)
* added: Montage method [donaldpcook](https://github.com/donaldpcook)
* added: Progressive option to thumb [mohebifar](https://github.com/mohebifar)
* added: Native gm auto-orient for use with gm >= 1.3.18 [bog](https://github.com/bog)
* added: Timeout support by passing the timeout option in milliseconds [marcbachmann](https://github.com/marcbachmann)
* fixed: density when using ImageMagick [syzer](https://github.com/syzer)
* fixed: resize behaviour for falsy values [adius](https://github.com/adius)
1.17.0 / 2014-10-28
==================
* changed: extended compare callback also returns the file names #297 [mastix](https://github.com/mastix)
* changed: pass spawn crash to callback #306 [medikoo](https://github.com/medikoo)
* changed: geometry supports arbitary string as first argument #330 [jdiez17](https://github.com/jdiez17)
* added: support for repage+ option #275 [desigens](https://github.com/desigens)
* added: added the dissolve command #300 [microadm](https://github.com/microadam)
* added: composite method #332 [jdiez17](https://github.com/jdiez17)
* fixed: cannot set tolerance to 0 #302 [rwky](https://github.com/rwky)
* fixed: handle empty buffers #330 [alcidesv](https://github.com/alcidesv)
1.16.0 / 2014-05-09
==================
* fixed; dropped "+" when 0 passed as vertical roll amt #267 [dwtkns](https://github.com/dwtkns)
* added; highlight-style support #272 [fdecampredon](https://github.com/fdecampredon)
1.15.0 / 2014-05-03
===================
* changed; gm.compare logic to always run the mse comparison as expected #258 [Vokkim](https://github.com/Vokkim)
* added; `tolerance` to gm.compare options object #258 [Vokkim](https://github.com/Vokkim)
* added; option to set ImageMagick application path explicitly #250 (akreitals)
* fixed; gm.compare: support values like 9.51582e-05 #260 [normanrz](https://github.com/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](https://github.com/soupdiver)
1.8.1 / 2012-12-21
==================
* Avoid losing already set arguments on identify #105 #113 #109 [JNissi](https://github.com/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](https://github.com/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](https://github.com/danmilon)
1.6.1 / 2012-11-13
==================
* fixed regression; only pass additional params on error #96
1.6.0 / 2012-11-10
==================
* changed; rename internal buffer to _buffer #88 [kof](https://github.com/kof)
* changed; optimized identify getters (format, depth, size, color, filesize). #83 please read this for details: https://github.com/aheckmann/gm/commit/8fcf3f8f84a02cc2001da874cbebb89bf7084409
* added; visionmedia/debug support
* added; `gm convert -thumbnail` support. _differs from thumb()._ [danmilon](https://github.com/danmilon)
* fixed; -rotate 0 support #90
* fixed; multi-execution of same gm instance arguments corruption
* fixed; gracefully handle parser errors #94 [eldilibra](https://github.com/eldilibra)
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](https://github.com/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
================================================
FILE: README.md
================================================
# 2025-02-24 This project is not maintained
Instead of using this project, execute the `gm` or `magick` binaries using
[`cross-spawn`](https://www.npmjs.com/package/cross-spawn) directly.
Nearly [15 years ago](https://github.com/aheckmann/gm/commit/defc7360d70d87f7a13da4f6e2ef0104594776b9) I started this project as part of my start up which I sold later that year (2010). Having not used this project in over a decade and with no contributors for years, it's time to officially sunset `gm`.
No further Issues will be addressed. No Pull Requests will be merged. No new commits or npm releases will be made.
---
😍 _Massive **thank you** to [everyone](https://github.com/aheckmann/gm/graphs/contributors) who contributed to this project over the years._ 😍
---
## I want to continue using gm. What do I do?
All past `gm` releases published to the npm registry will continue to be available for install. However, you should **prioritize moving off of this project to an alternative** because the risk of unpatched vulnerabilities in this project will continue to _increase_ over time. No new commits will land and no new releases will be published.
The most obvious alternative to `gm` I see is installing [cross-spawn](https://www.npmjs.com/package/cross-spawn) and executing the GraphicsMagick or ImageMagick binaries directly, after all, that's pretty much all this project did. There may be other `gm` alternatives on npm but I don't what they are offhand so you'll need to search for something suitable yourself.
---
# gm [](https://travis-ci.org/aheckmann/gm) [](https://www.npmjs.org/package/gm)
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](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:
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+](https://imagemagick.org/script/porting.php)
```js
const fs = require('fs')
const gm = require('gm').subClass({ imageMagick: '7+' });
```
Or, to enable ImageMagick legacy mode (for ImageMagick version < 7)
```js
const fs = require('fs')
const gm = require('gm').subClass({ imageMagick: true });
```
## Specify the executable path
Optionally specify the path to the executable.
```js
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
```js
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
```js
// 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
```js
// 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:
```bash
gm "convert" "label:Offline" "PNG:-"
```
However, using `gm().label()` may not work as intended for you:
```js
gm()
.label('Offline')
.stream();
```
would yield:
```bash
gm "convert" "-label" "\"Offline\"" "PNG:-"
```
Instead, you can use `gm().out()`:
```js
gm()
.out('label:Offline')
.stream();
```
which correctly yields:
```bash
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](http://www.imagemagick.org/script/escape.php) when using `gm().identify(format, callback)`.
For example,
```js
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](https://github.com/aheckmann/gm/wiki/GraphicsMagick-and-ImageMagick-versions).
## Examples:
Check out the [examples](http://github.com/aheckmann/gm/tree/master/examples/) directory to play around.
Also take a look at the [extending gm](http://wiki.github.com/aheckmann/gm/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](http://github.com/aheckmann/gm/blob/master/examples/new.js) 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
- getters
- [size](http://aheckmann.github.io/gm/docs.html#getters) - returns the size (WxH) of the image
- [orientation](http://aheckmann.github.io/gm/docs.html#getters) - returns the EXIF orientation of the image
- [format](http://aheckmann.github.io/gm/docs.html#getters) - returns the image format (gif, jpeg, png, etc)
- [depth](http://aheckmann.github.io/gm/docs.html#getters) - returns the image color depth
- [color](http://aheckmann.github.io/gm/docs.html#getters) - returns the number of colors
- [res](http://aheckmann.github.io/gm/docs.html#getters) - returns the image resolution
- [filesize](http://aheckmann.github.io/gm/docs.html#getters) - returns image filesize
- [identify](http://aheckmann.github.io/gm/docs.html#getters) - returns all image data available. Takes an optional format string.
- manipulation
- [adjoin](http://aheckmann.github.io/gm/docs.html#adjoin)
- [affine](http://aheckmann.github.io/gm/docs.html#affine)
- [antialias](http://aheckmann.github.io/gm/docs.html#antialias)
- [append](http://aheckmann.github.io/gm/docs.html#append)
- [authenticate](http://aheckmann.github.io/gm/docs.html#authenticate)
- [autoOrient](http://aheckmann.github.io/gm/docs.html#autoOrient)
- [average](http://aheckmann.github.io/gm/docs.html#average)
- [backdrop](http://aheckmann.github.io/gm/docs.html#backdrop)
- [bitdepth](http://aheckmann.github.io/gm/docs.html#bitdepth)
- [blackThreshold](http://aheckmann.github.io/gm/docs.html#blackThreshold)
- [bluePrimary](http://aheckmann.github.io/gm/docs.html#bluePrimary)
- [blur](http://aheckmann.github.io/gm/docs.html#blur)
- [border](http://aheckmann.github.io/gm/docs.html#border)
- [borderColor](http://aheckmann.github.io/gm/docs.html#borderColor)
- [box](http://aheckmann.github.io/gm/docs.html#box)
- [channel](http://aheckmann.github.io/gm/docs.html#channel)
- [charcoal](http://aheckmann.github.io/gm/docs.html#charcoal)
- [chop](http://aheckmann.github.io/gm/docs.html#chop)
- [clip](http://aheckmann.github.io/gm/docs.html#clip)
- [coalesce](http://aheckmann.github.io/gm/docs.html#coalesce)
- [colors](http://aheckmann.github.io/gm/docs.html#colors)
- [colorize](http://aheckmann.github.io/gm/docs.html#colorize)
- [colorMap](http://aheckmann.github.io/gm/docs.html#colorMap)
- [colorspace](http://aheckmann.github.io/gm/docs.html#colorspace)
- [comment](http://aheckmann.github.io/gm/docs.html#comment)
- [compose](http://aheckmann.github.io/gm/docs.html#compose)
- [compress](http://aheckmann.github.io/gm/docs.html#compress)
- [contrast](http://aheckmann.github.io/gm/docs.html#contrast)
- [convolve](http://aheckmann.github.io/gm/docs.html#convolve)
- [createDirectories](http://aheckmann.github.io/gm/docs.html#createDirectories)
- [crop](http://aheckmann.github.io/gm/docs.html#crop)
- [cycle](http://aheckmann.github.io/gm/docs.html#cycle)
- [deconstruct](http://aheckmann.github.io/gm/docs.html#deconstruct)
- [delay](http://aheckmann.github.io/gm/docs.html#delay)
- [define](http://aheckmann.github.io/gm/docs.html#define)
- [density](http://aheckmann.github.io/gm/docs.html#density)
- [despeckle](http://aheckmann.github.io/gm/docs.html#despeckle)
- [dither](http://aheckmann.github.io/gm/docs.html#dither)
- [displace](http://aheckmann.github.io/gm/docs.html#dither)
- [display](http://aheckmann.github.io/gm/docs.html#display)
- [dispose](http://aheckmann.github.io/gm/docs.html#dispose)
- [dissolve](http://aheckmann.github.io/gm/docs.html#dissolve)
- [edge](http://aheckmann.github.io/gm/docs.html#edge)
- [emboss](http://aheckmann.github.io/gm/docs.html#emboss)
- [encoding](http://aheckmann.github.io/gm/docs.html#encoding)
- [enhance](http://aheckmann.github.io/gm/docs.html#enhance)
- [endian](http://aheckmann.github.io/gm/docs.html#endian)
- [equalize](http://aheckmann.github.io/gm/docs.html#equalize)
- [extent](http://aheckmann.github.io/gm/docs.html#extent)
- [file](http://aheckmann.github.io/gm/docs.html#file)
- [filter](http://aheckmann.github.io/gm/docs.html#filter)
- [flatten](http://aheckmann.github.io/gm/docs.html#flatten)
- [flip](http://aheckmann.github.io/gm/docs.html#flip)
- [flop](http://aheckmann.github.io/gm/docs.html#flop)
- [foreground](http://aheckmann.github.io/gm/docs.html#foreground)
- [frame](http://aheckmann.github.io/gm/docs.html#frame)
- [fuzz](http://aheckmann.github.io/gm/docs.html#fuzz)
- [gamma](http://aheckmann.github.io/gm/docs.html#gamma)
- [gaussian](http://aheckmann.github.io/gm/docs.html#gaussian)
- [geometry](http://aheckmann.github.io/gm/docs.html#geometry)
- [gravity](http://aheckmann.github.io/gm/docs.html#gravity)
- [greenPrimary](http://aheckmann.github.io/gm/docs.html#greenPrimary)
- [highlightColor](http://aheckmann.github.io/gm/docs.html#highlightColor)
- [highlightStyle](http://aheckmann.github.io/gm/docs.html#highlightStyle)
- [iconGeometry](http://aheckmann.github.io/gm/docs.html#iconGeometry)
- [implode](http://aheckmann.github.io/gm/docs.html#implode)
- [intent](http://aheckmann.github.io/gm/docs.html#intent)
- [interlace](http://aheckmann.github.io/gm/docs.html#interlace)
- [label](http://aheckmann.github.io/gm/docs.html#label)
- [lat](http://aheckmann.github.io/gm/docs.html#lat)
- [level](http://aheckmann.github.io/gm/docs.html#level)
- [list](http://aheckmann.github.io/gm/docs.html#list)
- [limit](http://aheckmann.github.io/gm/docs.html#limit)
- [log](http://aheckmann.github.io/gm/docs.html#log)
- [loop](http://aheckmann.github.io/gm/docs.html#loop)
- [lower](http://aheckmann.github.io/gm/docs.html#lower)
- [magnify](http://aheckmann.github.io/gm/docs.html#magnify)
- [map](http://aheckmann.github.io/gm/docs.html#map)
- [matte](http://aheckmann.github.io/gm/docs.html#matte)
- [matteColor](http://aheckmann.github.io/gm/docs.html#matteColor)
- [mask](http://aheckmann.github.io/gm/docs.html#mask)
- [maximumError](http://aheckmann.github.io/gm/docs.html#maximumError)
- [median](http://aheckmann.github.io/gm/docs.html#median)
- [minify](http://aheckmann.github.io/gm/docs.html#minify)
- [mode](http://aheckmann.github.io/gm/docs.html#mode)
- [modulate](http://aheckmann.github.io/gm/docs.html#modulate)
- [monitor](http://aheckmann.github.io/gm/docs.html#monitor)
- [monochrome](http://aheckmann.github.io/gm/docs.html#monochrome)
- [morph](http://aheckmann.github.io/gm/docs.html#morph)
- [mosaic](http://aheckmann.github.io/gm/docs.html#mosaic)
- [motionBlur](http://aheckmann.github.io/gm/docs.html#motionBlur)
- [name](http://aheckmann.github.io/gm/docs.html#name)
- [negative](http://aheckmann.github.io/gm/docs.html#negative)
- [noise](http://aheckmann.github.io/gm/docs.html#noise)
- [noop](http://aheckmann.github.io/gm/docs.html#noop)
- [normalize](http://aheckmann.github.io/gm/docs.html#normalize)
- [noProfile](http://aheckmann.github.io/gm/docs.html#profile)
- [opaque](http://aheckmann.github.io/gm/docs.html#opaque)
- [operator](http://aheckmann.github.io/gm/docs.html#operator)
- [orderedDither](http://aheckmann.github.io/gm/docs.html#orderedDither)
- [outputDirectory](http://aheckmann.github.io/gm/docs.html#outputDirectory)
- [paint](http://aheckmann.github.io/gm/docs.html#paint)
- [page](http://aheckmann.github.io/gm/docs.html#page)
- [pause](http://aheckmann.github.io/gm/docs.html#pause)
- [pen](http://aheckmann.github.io/gm/docs.html#pen)
- [ping](http://aheckmann.github.io/gm/docs.html#ping)
- [pointSize](http://aheckmann.github.io/gm/docs.html#pointSize)
- [preview](http://aheckmann.github.io/gm/docs.html#preview)
- [process](http://aheckmann.github.io/gm/docs.html#process)
- [profile](http://aheckmann.github.io/gm/docs.html#profile)
- [progress](http://aheckmann.github.io/gm/docs.html#progress)
- [quality](http://aheckmann.github.io/gm/docs.html#quality)
- [raise](http://aheckmann.github.io/gm/docs.html#raise)
- [rawSize](http://aheckmann.github.io/gm/docs.html#rawSize)
- [randomThreshold](http://aheckmann.github.io/gm/docs.html#randomThreshold)
- [recolor](http://aheckmann.github.io/gm/docs.html#recolor)
- [redPrimary](http://aheckmann.github.io/gm/docs.html#redPrimary)
- [region](http://aheckmann.github.io/gm/docs.html#region)
- [remote](http://aheckmann.github.io/gm/docs.html#remote)
- [render](http://aheckmann.github.io/gm/docs.html#render)
- [repage](http://aheckmann.github.io/gm/docs.html#repage)
- [resample](http://aheckmann.github.io/gm/docs.html#resample)
- [resize](http://aheckmann.github.io/gm/docs.html#resize)
- [roll](http://aheckmann.github.io/gm/docs.html#roll)
- [rotate](http://aheckmann.github.io/gm/docs.html#rotate)
- [sample](http://aheckmann.github.io/gm/docs.html#sample)
- [samplingFactor](http://aheckmann.github.io/gm/docs.html#samplingFactor)
- [scale](http://aheckmann.github.io/gm/docs.html#scale)
- [scene](http://aheckmann.github.io/gm/docs.html#scene)
- [scenes](http://aheckmann.github.io/gm/docs.html#scenes)
- [screen](http://aheckmann.github.io/gm/docs.html#screen)
- [segment](http://aheckmann.github.io/gm/docs.html#segment)
- [sepia](http://aheckmann.github.io/gm/docs.html#sepia)
- [set](http://aheckmann.github.io/gm/docs.html#set)
- [setFormat](http://aheckmann.github.io/gm/docs.html#setformat)
- [shade](http://aheckmann.github.io/gm/docs.html#shade)
- [shadow](http://aheckmann.github.io/gm/docs.html#shadow)
- [sharedMemory](http://aheckmann.github.io/gm/docs.html#sharedMemory)
- [sharpen](http://aheckmann.github.io/gm/docs.html#sharpen)
- [shave](http://aheckmann.github.io/gm/docs.html#shave)
- [shear](http://aheckmann.github.io/gm/docs.html#shear)
- [silent](http://aheckmann.github.io/gm/docs.html#silent)
- [solarize](http://aheckmann.github.io/gm/docs.html#solarize)
- [snaps](http://aheckmann.github.io/gm/docs.html#snaps)
- [stegano](http://aheckmann.github.io/gm/docs.html#stegano)
- [stereo](http://aheckmann.github.io/gm/docs.html#stereo)
- [strip](http://aheckmann.github.io/gm/docs.html#strip) _imagemagick only_
- [spread](http://aheckmann.github.io/gm/docs.html#spread)
- [swirl](http://aheckmann.github.io/gm/docs.html#swirl)
- [textFont](http://aheckmann.github.io/gm/docs.html#textFont)
- [texture](http://aheckmann.github.io/gm/docs.html#texture)
- [threshold](http://aheckmann.github.io/gm/docs.html#threshold)
- [thumb](http://aheckmann.github.io/gm/docs.html#thumb)
- [tile](http://aheckmann.github.io/gm/docs.html#tile)
- [transform](http://aheckmann.github.io/gm/docs.html#transform)
- [transparent](http://aheckmann.github.io/gm/docs.html#transparent)
- [treeDepth](http://aheckmann.github.io/gm/docs.html#treeDepth)
- [trim](http://aheckmann.github.io/gm/docs.html#trim)
- [type](http://aheckmann.github.io/gm/docs.html#type)
- [update](http://aheckmann.github.io/gm/docs.html#update)
- [units](http://aheckmann.github.io/gm/docs.html#units)
- [unsharp](http://aheckmann.github.io/gm/docs.html#unsharp)
- [usePixmap](http://aheckmann.github.io/gm/docs.html#usePixmap)
- [view](http://aheckmann.github.io/gm/docs.html#view)
- [virtualPixel](http://aheckmann.github.io/gm/docs.html#virtualPixel)
- [visual](http://aheckmann.github.io/gm/docs.html#visual)
- [watermark](http://aheckmann.github.io/gm/docs.html#watermark)
- [wave](http://aheckmann.github.io/gm/docs.html#wave)
- [whitePoint](http://aheckmann.github.io/gm/docs.html#whitePoint)
- [whiteThreshold](http://aheckmann.github.io/gm/docs.html#whiteThreshold)
- [window](http://aheckmann.github.io/gm/docs.html#window)
- [windowGroup](http://aheckmann.github.io/gm/docs.html#windowGroup)
- drawing primitives
- [draw](http://aheckmann.github.io/gm/docs.html#draw)
- [drawArc](http://aheckmann.github.io/gm/docs.html#drawArc)
- [drawBezier](http://aheckmann.github.io/gm/docs.html#drawBezier)
- [drawCircle](http://aheckmann.github.io/gm/docs.html#drawCircle)
- [drawEllipse](http://aheckmann.github.io/gm/docs.html#drawEllipse)
- [drawLine](http://aheckmann.github.io/gm/docs.html#drawLine)
- [drawPoint](http://aheckmann.github.io/gm/docs.html#drawPoint)
- [drawPolygon](http://aheckmann.github.io/gm/docs.html#drawPolygon)
- [drawPolyline](http://aheckmann.github.io/gm/docs.html#drawPolyline)
- [drawRectangle](http://aheckmann.github.io/gm/docs.html#drawRectangle)
- [drawText](http://aheckmann.github.io/gm/docs.html#drawText)
- [fill](http://aheckmann.github.io/gm/docs.html#fill)
- [font](http://aheckmann.github.io/gm/docs.html#font)
- [fontSize](http://aheckmann.github.io/gm/docs.html#fontSize)
- [stroke](http://aheckmann.github.io/gm/docs.html#stroke)
- [strokeWidth](http://aheckmann.github.io/gm/docs.html#strokeWidth)
- [setDraw](http://aheckmann.github.io/gm/docs.html#setDraw)
- image output
- **write** - writes the processed image data to the specified filename
- **stream** - provides a `ReadableStream` with the processed image data
- **toBuffer** - returns the image as a `Buffer` instead of a stream
## 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)
```js
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`.
```js
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.
```js
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])
```js
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)
```js
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](https://github.com/aheckmann/gm/contributors)
## Inspiration
http://github.com/quiiver/magickal-node
## Plugins
[https://github.com/aheckmann/gm/wiki](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](aaron.heckmann+github@gmail.com)
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.
================================================
FILE: examples/append.js
================================================
var gm = require('../')
, dir = __dirname + '/imgs'
, imgs = 'lost.png original.jpg'.split(' ').map(function (img) {
return dir + '/' + img
})
, out = dir + '/append.jpg'
gm(imgs[0])
.append(imgs[1])
.append()
.background('#222')
.write(out, function (err) {
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
require('child_process').exec('open ' + out)
});
================================================
FILE: examples/background.js
================================================
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + "/original.jpg")
.crop(140,100)
.background("#FF0000")
.extent(340,300)
.write(dir + '/background.jpg', function (err) {
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
});
================================================
FILE: examples/bitdepth.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.bitdepth(2)
.write(dir + '/bitdepth.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/blur.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.blur(19, 10)
.write(dir + '/blur.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/changeFormat.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.write(dir + '/original.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/charcoal.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.charcoal(1)
.write(dir + '/charcoal.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/chop.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.chop(54, 1, 307, 1)
.write(dir + "/chop.jpg", function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/colorize.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.colorize(80, 0, 30)
.write(dir + '/colorize.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/colors.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.colors(16)
.write(dir + '/colors.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/comment.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.comment("%m:%f %wx%h")
.write(dir + '/comment.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/compare.js
================================================
var gm = require('../')
, dir = __dirname + '/imgs'
, imgs = 'bitdepth.png original.jpg'.split(' ').map(function (img) {
return dir + '/' + img
})
, out = dir + '/compare.jpg'
gm.compare(imgs[0], imgs[1], { highlightColor: "#fff", file: out }, function (err) {
if (err) return console.dir(arguments)
console.log('The images are equal: %s', arguments[1]);
console.log('Actual equality: %d', arguments[2]);
console.log(this.outname + " created :: " + arguments[3]);
require('child_process').exec('open ' + out);
});
================================================
FILE: examples/contrast.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.contrast(2)
.write(dir + '/contrast.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/crop.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.crop(200, 155, 300, 0)
.write(dir + "/crop.jpg", function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/cycle.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.cycle(4)
.write(dir + '/cycle.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/despeckle.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.despeckle()
.write(dir + '/despeckle.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/dither.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.monochrome()
.dither()
.write(dir + '/dither.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/drawing.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.blur(8, 4)
.stroke("red", 7)
.fill("#ffffffbb")
.drawLine(20, 10, 50, 40)
.fill("#2c2")
.stroke("blue", 1)
.drawRectangle(40, 10, 50, 20)
.drawRectangle(60, 10, 70, 20, 3)
.drawArc(80, 10, 90, 20, 0, 180)
.drawEllipse(105, 15, 3, 5)
.drawCircle(125, 15, 120, 15)
.drawPolyline([140, 10], [143, 13], [145, 13], [147, 15], [145, 17], [143, 19])
.drawPolygon([160, 10], [163, 13], [165, 13], [167, 15], [165, 17], [163, 19])
.drawBezier([180, 10], [183, 13], [185, 13], [187, 15], [185, 17], [183, 19])
.fontSize(68)
.stroke("#efe", 2)
.fill("#888")
.drawText(-20, 98, "graphics magick")
.write(dir + '/drawing.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/edge.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.edge(2)
.write(dir + '/edge.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/emboss.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.emboss(2)
.write(dir + '/emboss.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/enhance.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.enhance()
.write(dir + '/enhance.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/equalize.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.equalize()
.write(dir + '/equalize.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/extent.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.resize(200,100)
.extent(300, 300)
.write(dir + '/extent.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/flatten.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/layers.psd')
.flatten()
.write(dir + "/unlayered.jpg", function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/flip.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.flip()
.write(dir + '/flip.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/flop.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.flop()
.write(dir + '/flop.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/gamma.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.gamma(1.7, 2.3, 1.3)
.write(dir + '/gamma.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/getters.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
var methods =
[ "size"
, "identify"
, "format"
, "depth"
, "color"
, "res"
, "filesize"
]
var image = gm(dir + '/original.png')
methods.forEach(function(method){
image[method](function(err, result){
console.log(method + " result:")
console.dir(result)
})
})
================================================
FILE: examples/gravity.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.resize(200,100)
.gravity("South") // Be sure to use gravity BEFORE extent
.extent(300, 300)
.write(dir + '/gravity.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/implode.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.implode(0.8)
.write(dir + '/implode.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/label.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.label("%m:%f %wx%h")
.write(dir + '/label.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/limit.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.limit("memory", "32MB")
.limit("map", "64MB")
.write(dir + '/limit.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/lower.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.lower(10, 14)
.write(dir + '/lower.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/magnify.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.magnify()
.write(dir + '/magnify.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/median.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.median(4)
.write(dir + '/median.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/minify.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.minify()
.write(dir + '/minify.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/modulate.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.modulate(120, 100, 80)
.write(dir + '/modulate.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/monochrome.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.monochrome()
.write(dir + '/monochrome.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/morph.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.morph(dir + '/morpher.jpg', dir + '/morph.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/negative.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.negative()
.write(dir + '/negative.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/new.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(525, 110, "#00ff55aa")
.fontSize(68)
.stroke("#efe", 2)
.fill("#555")
.drawText(20, 72, "graphics")
.fill("#fa0")
.drawText(274, 72, " magick")
.write(dir + '/new.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/noise1.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.noise(0.3)
.write(dir + '/noise1.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/noise2.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.noise("laplacian")
.write(dir + '/noise2.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/paint.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.paint(2)
.write(dir + '/paint.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/quality.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.quality(5)
.write(dir + '/quality.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/raise.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.raise(10, 14)
.write(dir + '/raise.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/region.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
// region must come before other affected arguments
.region(130, 170, 307, 00).charcoal(1)
.write(dir + '/region.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/resample.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.resample(420, 120)
.write(dir + '/resample.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/resize.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.resize(58, 50, '%')
.write(dir + '/resize.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/roll.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.roll(40,-100)
.quality(100)
.write(dir + '/roll.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/rotate.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.rotate('red', -30)
.write(dir + '/rotate.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/scale.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.resize(58, 20)
.write(dir + '/scale.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/sepia.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.sepia()
.write(dir + '/sepia.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: examples/sharpen.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.sharpen(19, 10)
.write(dir + '/sharpen.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/size.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
var methods =
[ "size"
]
var image = gm(dir + '/original.png')
methods.forEach(function(method){
image[method](function(err, result){
console.log(method + " result:")
console.dir(result)
})
})
================================================
FILE: examples/solarize.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.solarize(68.9)
.write(dir + '/solarize.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/source_buffer.js
================================================
var gm = require('../')
, fs = require('fs')
, dir = __dirname + '/../examples/imgs'
var buf = fs.readFileSync(dir + '/original.jpg');
gm(buf)
.noise('laplacian')
.write(dir + '/fromBuffer.png', function (err) {
if (err) return console.dir(arguments);
console.log(this.outname + ' created :: ' + arguments[3]);
});
================================================
FILE: examples/spread.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.spread(10)
.write(dir + '/spread.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/swirl.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.png')
.swirl(90) // degrees
.write(dir + '/swirl.png', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + ' created :: ' + arguments[3])
}
)
================================================
FILE: examples/thumb.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.thumb(150, 50, dir + '/thumb.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
});
================================================
FILE: examples/thumbExact.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.thumbExact(150, 50, dir + '/thumb.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
});
================================================
FILE: examples/thumbnail.js
================================================
var gm = require('../')
, dir = __dirname + '/imgs'
gm(dir + '/original.jpg')
.thumbnail(150, 150)
.write(dir + '/thumbnail.jpg', function(err){
if (err) return console.dir(arguments)
console.log(this.outname + " created :: " + arguments[3])
}
)
================================================
FILE: index.js
================================================
/**
* Module dependencies.
*/
var Stream = require('stream').Stream;
var EventEmitter = require('events').EventEmitter;
var util = require('util');
util.inherits(gm, EventEmitter);
/**
* Constructor.
*
* @param {String|Number} path - path to img source or ReadableStream or width of img to create
* @param {Number} [height] - optional filename of ReadableStream or height of img to create
* @param {String} [color] - optional hex background color of created img
*/
function gm (source, height, color) {
var width;
if (!(this instanceof gm)) {
return new gm(source, height, color);
}
EventEmitter.call(this);
this._options = {};
this.options(this.__proto__._options);
this.data = {};
this._in = [];
this._out = [];
this._outputFormat = null;
this._subCommand = 'convert';
if (source instanceof Stream) {
this.sourceStream = source;
source = height || 'unknown.jpg';
} else if (Buffer.isBuffer(source)) {
this.sourceBuffer = source;
source = height || 'unknown.jpg';
} else if (height) {
// new images
width = source;
source = "";
this.in("-size", width + "x" + height);
if (color) {
this.in("xc:"+ color);
}
}
if (typeof source === "string") {
// then source is a path
// parse out gif frame brackets from filename
// since stream doesn't use source path
// eg. "filename.gif[0]"
var frames = source.match(/(\[.+\])$/);
if (frames) {
this.sourceFrames = source.substr(frames.index, frames[0].length);
source = source.substr(0, frames.index);
}
}
this.source = source;
this.addSrcFormatter(function (src) {
// must be first source formatter
var inputFromStdin = this.sourceStream || this.sourceBuffer;
var ret = inputFromStdin ? '-' : this.source;
const fileNameProvied = typeof height === 'string';
if (inputFromStdin && fileNameProvied && /\.ico$/i.test(this.source)) {
ret = `ico:-`;
}
if (ret && this.sourceFrames) ret += this.sourceFrames;
src.length = 0;
src[0] = ret;
});
}
/**
* Subclasses the gm constructor with custom options.
*
* @param {options} options
* @return {gm} the subclasses gm constructor
*/
var parent = gm;
gm.subClass = function subClass (options) {
function gm (source, height, color) {
if (!(this instanceof parent)) {
return new gm(source, height, color);
}
parent.call(this, source, height, color);
}
gm.prototype.__proto__ = parent.prototype;
gm.prototype._options = {};
gm.prototype.options(options);
return gm;
}
/**
* Augment the prototype.
*/
require("./lib/options")(gm.prototype);
require("./lib/getters")(gm);
require("./lib/args")(gm.prototype);
require("./lib/drawing")(gm.prototype);
require("./lib/convenience")(gm.prototype);
require("./lib/command")(gm.prototype);
require("./lib/compare")(gm.prototype);
require("./lib/composite")(gm.prototype);
require("./lib/montage")(gm.prototype);
/**
* Expose.
*/
module.exports = exports = gm;
module.exports.utils = require('./lib/utils');
module.exports.compare = require('./lib/compare')();
module.exports.version = require('./package.json').version;
================================================
FILE: lib/args.js
================================================
/**
* Dependencies
*/
var argsToArray = require('./utils').argsToArray;
var isUtil = require('./utils').isUtil;
/**
* Extend proto
*/
module.exports = function (proto) {
// change the specified frame.
// See #202.
proto.selectFrame = function (frame) {
if (typeof frame === 'number')
this.sourceFrames = '[' + frame + ']';
return this;
}
// define the sub-command to use, http://www.graphicsmagick.org/utilities.html
proto.command = proto.subCommand = function subCommand (name){
this._subCommand = name;
return this;
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-adjoin
proto.adjoin = function adjoin () {
return this.out("-adjoin");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-affine
proto.affine = function affine (matrix) {
return this.out("-affine", matrix);
}
proto.alpha = function alpha (type) {
if (!this._options.imageMagick) return new Error('Method -alpha is not supported by GraphicsMagick');
return this.out('-alpha', type);
}
/**
* Appends images to the list of "source" images.
*
* We may also specify either top-to-bottom or left-to-right
* behavior of the appending by passing a boolean argument.
*
* Examples:
*
* img = gm(src);
*
* // +append means left-to-right
* img.append(img1, img2) gm convert src img1 img2 -append
* img.append(img, true) gm convert src img +append
* img.append(img, false) gm convert src img -append
* img.append(img) gm convert src img -append
* img.append(img).append() gm convert src img -append
* img.append(img).append(true) gm convert src img +append
* img.append(img).append(true) gm convert src img +append
* img.append(img).background('#222) gm convert src img -background #222 +append
* img.append([img1,img2...],true)
* @param {String} or {Array} [img]
* @param {Boolean} [ltr]
* @see http://www.graphicsmagick.org/GraphicsMagick.html#details-append
*/
proto.append = function append (img, ltr) {
if (!this._append) {
this._append = [];
this.addSrcFormatter(function (src) {
this.out(this._append.ltr ? '+append' : '-append');
src.push.apply(src, this._append);
});
}
if (0 === arguments.length) {
this._append.ltr = false;
return this;
}
for (var i = 0; i < arguments.length; ++i) {
var arg = arguments[i];
switch (isUtil(arg)) {
case 'Boolean':
this._append.ltr = arg;
break;
case 'String':
this._append.push(arg);
break;
case 'Array':
for(var j=0,len=arg.length;j<len;j++){
if(isUtil(arg[j]) == 'String'){
this._append.push(arg[j]);
}
}
break;
}
}
return this;
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-authenticate
proto.authenticate = function authenticate (string) {
return this.out("-authenticate", string);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-average
proto.average = function average () {
return this.out("-average");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-backdrop
proto.backdrop = function backdrop () {
return this.out("-backdrop");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-black-threshold
proto.blackThreshold = function blackThreshold (red, green, blue, opacity) {
return this.out("-black-threshold", argsToArray(red, green, blue, opacity).join(','));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-blue-primary
proto.bluePrimary = function bluePrimary (x, y) {
return this.out("-blue-primary", argsToArray(x, y).join(','));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-border
proto.border = function border (width, height) {
return this.out("-border", width+"x"+height);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-bordercolor
proto.borderColor = function borderColor (color) {
return this.out("-bordercolor", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-box
proto.box = function box (color) {
return this.out("-box", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-channel
proto.channel = function channel (type) {
return this.out("-channel", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-chop
proto.chop = function chop (w, h, x, y) {
return this.in("-chop", w+"x"+h + "+"+(x||0)+"+"+(y||0));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-clip
proto.clip = function clip () {
return this.out("-clip");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-coalesce
proto.coalesce = function coalesce () {
return this.out("-coalesce");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-colorize
proto.colorize = function colorize (r, g, b) {
return this.out("-colorize", [r,g,b].join(","));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-colormap
proto.colorMap = function colorMap (type) {
return this.out("-colormap", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-compose
proto.compose = function compose (operator) {
return this.out("-compose", operator);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-compress
proto.compress = function compress (type) {
return this.out("-compress", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-kernel
proto.convolve = function convolve (kernel) {
return this.out("-convolve", kernel);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-create-directories
proto.createDirectories = function createDirectories () {
return this.out("-create-directories");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-deconstruct
proto.deconstruct = function deconstruct () {
return this.out("-deconstruct");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-define
proto.define = function define (value) {
return this.out("-define", value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-delay
proto.delay = function delay (value) {
return this.out("-delay", value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-displace
proto.displace = function displace (horizontalScale, verticalScale) {
return this.out("-displace", horizontalScale+'x'+verticalScale);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-display
proto.display = function display (value) {
return this.out("-display", value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-dispose
proto.dispose = function dispose (method) {
return this.out("-dispose", method);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-dissolve
proto.dissolve = function dissolve (percent) {
return this.out("-dissolve", percent+'%');
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-encoding
proto.encoding = function encoding (type) {
return this.out("-encoding", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-endian
proto.endian = function endian (type) {
return this.out("-endian", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-file
proto.file = function file (filename) {
return this.out("-file", filename);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-flatten
proto.flatten = function flatten () {
return this.out("-flatten");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-foreground
proto.foreground = function foreground (color) {
return this.out("-foreground", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-frame
proto.frame = function frame (width, height, outerBevelWidth, innerBevelWidth) {
if(arguments.length==0) return this.out("-frame");
return this.out("-frame", width+'x'+height+'+'+outerBevelWidth+'+'+innerBevelWidth);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-fuzz
proto.fuzz = function fuzz (distance, percent) {
return this.out("-fuzz", distance+(percent?'%':''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-gaussian
proto.gaussian = function gaussian (radius, sigma) {
return this.out("-gaussian", argsToArray(radius, sigma).join('x'));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-geometry
proto.geometry = function geometry (width, height, arg) {
// If the first argument is a string, and there is only one argument, this is a custom geometry command.
if(arguments.length == 1 && typeof arguments[0] === "string")
return this.out("-geometry", arguments[0]);
// Otherwise, return a resizing geometry command with an option alrgument.
return this.out("-geometry", width+'x'+height+(arg||''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-green-primary
proto.greenPrimary = function greenPrimary (x, y) {
return this.out("-green-primary", x+','+y);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-highlight-color
proto.highlightColor = function highlightColor (color) {
return this.out("-highlight-color", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-highlight-style
proto.highlightStyle = function highlightStyle (style) {
return this.out("-highlight-style", style);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-iconGeometry
proto.iconGeometry = function iconGeometry (geometry) {
return this.out("-iconGeometry", geometry);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-intent
proto.intent = function intent (type) {
return this.out("-intent", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-lat
proto.lat = function lat (width, height, offset, percent) {
return this.out("-lat", width+'x'+height+offset+(percent?'%':''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-level
proto.level = function level (blackPoint, gamma, whitePoint, percent) {
return this.out("-level", argsToArray(blackPoint, gamma, whitePoint).join(',')+(percent?'%':''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-list
proto.list = function list (type) {
return this.out("-list", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-log
proto.log = function log (string) {
return this.out("-log", string);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-loop
proto.loop = function loop (iterations) {
return this.out("-loop", iterations);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-map
proto.map = function map (filename) {
return this.out("-map", filename);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-mask
proto.mask = function mask (filename) {
return this.out("-mask", filename);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-matte
proto.matte = function matte () {
return this.out("-matte");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-mattecolor
proto.matteColor = function matteColor (color) {
return this.out("-mattecolor", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-maximum-error
proto.maximumError = function maximumError (limit) {
return this.out("-maximum-error", limit);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-mode
proto.mode = function mode (value) {
return this.out("-mode", value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-monitor
proto.monitor = function monitor () {
return this.out("-monitor");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-mosaic
proto.mosaic = function mosaic () {
return this.out("-mosaic");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-motion-blur
proto.motionBlur = function motionBlur (radius, sigma, angle) {
var arg=radius;
if (typeof sigma!='undefined') arg+='x'+sigma;
if (typeof angle!='undefined') arg+='+'+angle;
return this.out("-motion-blur", arg);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-name
proto.name = function name () {
return this.out("-name");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-noop
proto.noop = function noop () {
return this.out("-noop");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-normalize
proto.normalize = function normalize () {
return this.out("-normalize");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-opaque
proto.opaque = function opaque (color) {
return this.out("-opaque", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-operator
proto.operator = function operator (channel, operator, rvalue, percent) {
return this.out("-operator", channel, operator, rvalue+(percent?'%':''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-ordered-dither
proto.orderedDither = function orderedDither (channeltype, NxN) {
return this.out("-ordered-dither", channeltype, NxN);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-output-directory
proto.outputDirectory = function outputDirectory (directory) {
return this.out("-output-directory", directory);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-page
proto.page = function page (width, height, arg) {
return this.out("-page", width+'x'+height+(arg||''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-pause
proto.pause = function pause (seconds) {
return this.out("-pause", seconds);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-pen
proto.pen = function pen (color) {
return this.out("-pen", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-ping
proto.ping = function ping () {
return this.out("-ping");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-pointsize
proto.pointSize = function pointSize (value) {
return this.out("-pointsize", value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-preview
proto.preview = function preview (type) {
return this.out("-preview", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-process
proto.process = function process (command) {
return this.out("-process", command);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-profile
proto.profile = function profile (filename) {
return this.out("-profile", filename);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-progress
proto.progress = function progress () {
return this.out("+progress");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-random-threshold
proto.randomThreshold = function randomThreshold (channeltype, LOWxHIGH) {
return this.out("-random-threshold", channeltype, LOWxHIGH);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-recolor
proto.recolor = function recolor (matrix) {
return this.out("-recolor", matrix);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-red-primary
proto.redPrimary = function redPrimary (x, y) {
return this.out("-red-primary", x, y);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-remote
proto.remote = function remote () {
return this.out("-remote");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-render
proto.render = function render () {
return this.out("-render");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-repage
proto.repage = function repage (width, height, xoff, yoff, arg) {
if (arguments[0] === "+") return this.out("+repage");
return this.out("-repage", width+'x'+height+'+'+xoff+'+'+yoff+(arg||''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-sample
proto.sample = function sample (geometry) {
return this.out("-sample", geometry);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-sampling-factor
proto.samplingFactor = function samplingFactor (horizontalFactor, verticalFactor) {
return this.out("-sampling-factor", horizontalFactor+'x'+verticalFactor);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-scene
proto.scene = function scene (value) {
return this.out("-scene", value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-scenes
proto.scenes = function scenes (start, end) {
return this.out("-scenes", start+'-'+end);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-screen
proto.screen = function screen () {
return this.out("-screen");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-set
proto.set = function set (attribute, value) {
return this.out("-set", attribute, value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-segment
proto.segment = function segment (clusterThreshold, smoothingThreshold) {
return this.out("-segment", clusterThreshold+'x'+smoothingThreshold);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-shade
proto.shade = function shade (azimuth, elevation) {
return this.out("-shade", azimuth+'x'+elevation);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-shadow
proto.shadow = function shadow (radius, sigma) {
return this.out("-shadow", argsToArray(radius, sigma).join('x'));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-shared-memory
proto.sharedMemory = function sharedMemory () {
return this.out("-shared-memory");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-shave
proto.shave = function shave (width, height, percent) {
return this.out("-shave", width+'x'+height+(percent?'%':''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-shear
proto.shear = function shear (xDegrees, yDegreees) {
return this.out("-shear", xDegrees+'x'+yDegreees);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-silent
proto.silent = function silent (color) {
return this.out("-silent");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-size
proto.rawSize = function rawSize (width, height, offset) {
var off = 'undefined' != typeof offset
? '+' + offset
: '';
return this.out("-size", width +'x'+ height + off);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-snaps
proto.snaps = function snaps (value) {
return this.out("-snaps", value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-stegano
proto.stegano = function stegano (offset) {
return this.out("-stegano", offset);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-stereo
proto.stereo = function stereo () {
return this.out("-stereo");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-text-font
proto.textFont = function textFont (name) {
return this.out("-text-font", name);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-texture
proto.texture = function texture (filename) {
return this.out("-texture", filename);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-threshold
proto.threshold = function threshold (value, percent) {
return this.out("-threshold", value+(percent?'%':''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-thumbnail
proto.thumbnail = function thumbnail (w, h, options) {
options = options || "";
var geometry,
wIsValid = Boolean(w || w === 0),
hIsValid = Boolean(h || h === 0);
if (wIsValid && hIsValid) {
geometry = w + "x" + h + options
} else if (wIsValid) {
// GraphicsMagick requires <width>x<options>, ImageMagick requires <width><options>
geometry = (this._options.imageMagick) ? w + options : w +
'x' + options;
} else if (hIsValid) {
geometry = 'x' + h + options
} else {
return this
}
return this.out("-thumbnail", geometry);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-tile
proto.tile = function tile (filename) {
return this.out("-tile", filename);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-title
proto.title = function title (string) {
return this.out("-title", string);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-transform
proto.transform = function transform (color) {
return this.out("-transform", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-transparent
proto.transparent = function transparent (color) {
return this.out("-transparent", color);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-treedepth
proto.treeDepth = function treeDepth (value) {
return this.out("-treedepth", value);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-update
proto.update = function update (seconds) {
return this.out("-update", seconds);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-units
proto.units = function units (type) {
return this.out("-units", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-unsharp
proto.unsharp = function unsharp (radius, sigma, amount, threshold) {
var arg=radius;
if (typeof sigma != 'undefined') arg+='x'+sigma;
if (typeof amount != 'undefined') arg+='+'+amount;
if (typeof threshold != 'undefined') arg+='+'+threshold;
return this.out("-unsharp", arg);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-use-pixmap
proto.usePixmap = function usePixmap () {
return this.out("-use-pixmap");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-view
proto.view = function view (string) {
return this.out("-view", string);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-virtual-pixel
proto.virtualPixel = function virtualPixel (method) {
return this.out("-virtual-pixel", method);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-visual
proto.visual = function visual (type) {
return this.out("-visual", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-watermark
proto.watermark = function watermark (brightness, saturation) {
return this.out("-watermark", brightness+'x'+saturation);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-wave
proto.wave = function wave (amplitude, wavelength) {
return this.out("-wave", amplitude+'x'+wavelength);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-white-point
proto.whitePoint = function whitePoint (x, y) {
return this.out("-white-point", x+'x'+y);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-white-threshold
proto.whiteThreshold = function whiteThreshold (red, green, blue, opacity) {
return this.out("-white-threshold", argsToArray(red, green, blue, opacity).join(','));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-window
proto.window = function window (id) {
return this.out("-window", id);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-window-group
proto.windowGroup = function windowGroup () {
return this.out("-window-group");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-strip (graphicsMagick >= 1.3.15)
proto.strip = function strip () {
if (this._options.imageMagick) return this.out("-strip");
return this.noProfile().out("+comment");//Equivalent to "-strip" for all versions of graphicsMagick
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-interlace
proto.interlace = function interlace (type) {
return this.out("-interlace", type || "None");
}
// force output format
proto.setFormat = function setFormat (format) {
if (format) this._outputFormat = format;
return this;
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-resize
proto.resize = function resize (w, h, options) {
options = options || "";
var geometry,
wIsValid = Boolean(w || w === 0),
hIsValid = Boolean(h || h === 0);
if (wIsValid && hIsValid) {
geometry = w + "x" + h + options
} else if (wIsValid) {
// GraphicsMagick requires <width>x<options>, ImageMagick requires <width><options>
geometry = (this._options.imageMagick) ? w + options : w +
'x' + options;
} else if (hIsValid) {
geometry = 'x' + h + options
} else {
return this
}
return this.out("-resize", geometry);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-resize with '!' option
proto.resizeExact = function resize (w, h) {
var options = "!";
return proto.resize.apply(this, [w, h, options]);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-scale
proto.scale = function scale (w, h, options) {
options = options || "";
var geometry;
if (w && h) {
geometry = w + "x" + h + options
} else if (w && !h) {
geometry = (this._options.imageMagick) ? w + options : w + 'x' + options;
} else if (!w && h) {
geometry = 'x' + h + options
}
return this.out("-scale", geometry);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-filter
proto.filter = function filter (val) {
return this.out("-filter", val);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-density
proto.density = function density (w, h) {
if (w && !h && this._options.imageMagick) {
// GraphicsMagick requires <width>x<height>y, ImageMagick may take dpi<resolution>
// recommended 300dpi for higher quality
return this.in("-density", w);
}
return this.in("-density", w +"x"+ h);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-profile
proto.noProfile = function noProfile () {
this.out('+profile', '"*"');
return this;
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-resample
proto.resample = function resample (w, h) {
return this.out("-resample", w+"x"+h);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-rotate
proto.rotate = function rotate (color, deg) {
return this.out("-background", color, "-rotate", String(deg || 0));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-flip
proto.flip = function flip () {
return this.out("-flip");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-flop
proto.flop = function flop () {
return this.out("-flop");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-crop
proto.crop = function crop (w, h, x, y, percent) {
if (this.inputIs('jpg')) {
// avoid error "geometry does not contain image (unable to crop image)" - gh-17
var index = this._in.indexOf('-size');
if (~index) {
this._in.splice(index, 2);
}
}
return this.out("-crop", w + "x" + h + "+" + (x || 0) + "+" + (y || 0) + (percent ? '%' : ''));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-magnify
proto.magnify = function magnify (factor) {
return this.in("-magnify");
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.minify = function minify () {
return this.in("-minify")
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-quality
proto.quality = function quality (val) {
return this.in("-quality", val || 75);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-blur
proto.blur = function blur (radius, sigma) {
return this.out("-blur", radius + (sigma ? "x"+sigma : ""));
}
// http://www.graphicsmagick.org/convert.html
proto.charcoal = function charcoal (factor) {
return this.out("-charcoal", factor || 2);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-modulate
proto.modulate = function modulate (b, s, h) {
return this.out("-modulate", [b,s,h].join(","));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-antialias
// note: antialiasing is enabled by default
proto.antialias = function antialias (disable) {
return false === disable
? this.out("+antialias")
: this;
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-depth
proto.bitdepth = function bitdepth (val) {
return this.out("-depth", val);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-colors
proto.colors = function colors (val) {
return this.out("-colors", val || 128);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-colorspace
proto.colorspace = function colorspace (val) {
return this.out("-colorspace", val);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-comment
proto.comment = comment("-comment");
// http://www.graphicsmagick.org/GraphicsMagick.html#details-contrast
proto.contrast = function contrast (mult) {
var arg = (parseInt(mult, 10) || 0) > 0
? "+contrast"
: "-contrast";
mult = Math.abs(mult) || 1;
while (mult--) {
this.out(arg);
}
return this;
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-cycle
proto.cycle = function cycle (amount) {
return this.out("-cycle", amount || 2);
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.despeckle = function despeckle () {
return this.out("-despeckle");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-dither
// note: either colors() or monochrome() must be used for this
// to take effect.
proto.dither = function dither (on) {
var sign = false === on
? "+"
: "-";
return this.out(sign + "dither");
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.monochrome = function monochrome () {
return this.out("-monochrome");
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.edge = function edge (radius) {
return this.out("-edge", radius || 1);
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.emboss = function emboss (radius) {
return this.out("-emboss", radius || 1);
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.enhance = function enhance () {
return this.out("-enhance");
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.equalize = function equalize () {
return this.out("-equalize");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-gamma
proto.gamma = function gamma (r, g, b) {
return this.out("-gamma", [r,g,b].join());
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.implode = function implode (factor) {
return this.out("-implode", factor || 1);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-comment
proto.label = comment("-label");
var limits = [ "disk", "file", "map", "memory", "pixels", "threads"];
// http://www.graphicsmagick.org/GraphicsMagick.html#details-limit
proto.limit = function limit (type, val) {
type = type.toLowerCase();
if (!~limits.indexOf(type)) {
return this;
}
return this.out("-limit", type, val);
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.median = function median (radius) {
return this.out("-median", radius || 1);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-negate
proto.negative = function negative (grayscale) {
var sign = grayscale ? "+" : "-";
return this.out(sign + "negate");
}
var noises = [
"uniform"
, "gaussian"
, "multiplicative"
, "impulse"
, "laplacian"
, "poisson"
];
// http://www.graphicsmagick.org/GraphicsMagick.html#details-noise
proto.noise = function noise (radius) {
radius = (String(radius)).toLowerCase();
var sign = ~noises.indexOf(radius)
? "+"
: "-";
return this.out(sign + "noise", radius);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-paint
proto.paint = function paint (radius) {
return this.out("-paint", radius);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-raise
proto.raise = function raise (w, h) {
return this.out("-raise", (w||0)+"x"+(h||0));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-raise
proto.lower = function lower (w, h) {
return this.out("+raise", (w||0)+"x"+(h||0));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-region
proto.region = function region (w, h, x, y) {
w = w || 0;
h = h || 0;
x = x || 0;
y = y || 0;
return this.out("-region", w + "x" + h + "+" + x + "+" + y);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-roll
proto.roll = function roll (x, y) {
x = ((x = parseInt(x, 10) || 0) >= 0 ? "+" : "") + x;
y = ((y = parseInt(y, 10) || 0) >= 0 ? "+" : "") + y;
return this.out("-roll", x+y);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-sharpen
proto.sharpen = function sharpen (radius, sigma) {
sigma = sigma
? "x" + sigma
: "";
return this.out("-sharpen", radius + sigma);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-solarize
proto.solarize = function solarize (factor) {
return this.out("-solarize", (factor || 1)+"%");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-spread
proto.spread = function spread (amount) {
return this.out("-spread", amount || 5);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-swirl
proto.swirl = function swirl (degrees) {
return this.out("-swirl", degrees || 180);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-type
proto.type = function type (type) {
return this.in("-type", type);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-trim
proto.trim = function trim () {
return this.out("-trim");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-extent
proto.extent = function extent (w, h, options) {
options = options || "";
var geometry;
if (w && h) {
geometry = w + "x" + h + options
} else if (w && !h) {
geometry = (this._options.imageMagick) ? w + options : w + 'x' + options;
} else if (!w && h) {
geometry = 'x' + h + options
}
return this.out("-extent", geometry);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-gravity
// Be sure to use gravity BEFORE extent
proto.gravity = function gravity (type) {
if (!type || !~gravity.types.indexOf(type)) {
type = "NorthWest"; // Documented default.
}
return this.out("-gravity", type);
}
proto.gravity.types = [
"NorthWest"
, "North"
, "NorthEast"
, "West"
, "Center"
, "East"
, "SouthWest"
, "South"
, "SouthEast"
];
// http://www.graphicsmagick.org/GraphicsMagick.html#details-flatten
proto.flatten = function flatten () {
return this.out("-flatten");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-background
proto.background = function background (color) {
return this.in("-background", color);
}
};
/**
* Generates a handler for comments/labels.
*/
function comment (arg) {
return function (format) {
format = String(format);
format = "@" == format.charAt(0)
? format.substring(1)
: format;
return this.out(arg, '"' + format + '"');
}
}
================================================
FILE: lib/command.js
================================================
/**
* Module dependencies.
*/
var spawn = require('cross-spawn');
var utils = require('./utils');
var debug = require('debug')('gm');
var series = require('array-series');
var PassThrough = require('stream').PassThrough;
/**
* Error messaging.
*/
var noBufferConcat = 'gm v1.9.0+ required node v0.8+. Please update your version of node, downgrade gm < 1.9, or do not use `bufferStream`.';
/**
* Extend proto
*/
module.exports = function (proto) {
function args (prop) {
return function args () {
var len = arguments.length;
var a = [];
var i = 0;
for (; i < len; ++i) {
a.push(arguments[i]);
}
this[prop] = this[prop].concat(a);
return this;
}
}
function streamToUnemptyBuffer(stream, callback) {
var done = false
var buffers = []
stream.on('data', function (data) {
buffers.push(data)
})
stream.on('end', function () {
if (done)
return
done = true
let result = Buffer.concat(buffers)
buffers = null
if (result.length === 0) {
const err = new Error("Stream yields empty buffer");
callback(err, null);
} else {
callback(null, result);
}
})
stream.on('error', function (err) {
done = true
buffers = null
callback(err)
})
}
proto.in = args('_in');
proto.out = args('_out');
proto._preprocessor = [];
proto.preprocessor = args('_preprocessor');
/**
* Execute the command and write the image to the specified file name.
*
* @param {String} name
* @param {Function} callback
* @return {Object} gm
*/
proto.write = function write (name, callback) {
if (!callback) callback = name, name = null;
if ("function" !== typeof callback) {
throw new TypeError("gm().write() expects a callback function")
}
if (!name) {
return callback(TypeError("gm().write() expects a filename when writing new files"));
}
this.outname = name;
var self = this;
this._preprocess(function (err) {
if (err) return callback(err);
self._spawn(self.args(), true, callback);
});
}
/**
* Execute the command and return stdin and stderr
* ReadableStreams providing the image data.
* If no callback is passed, a "through" stream will be returned,
* and stdout will be piped through, otherwise the error will be passed.
*
* @param {String} format (optional)
* @param {Function} callback (optional)
* @return {Stream}
*/
proto.stream = function stream (format, callback) {
if (!callback && typeof format === 'function') {
callback = format;
format = null;
}
var throughStream;
if ("function" !== typeof callback) {
throughStream = new PassThrough();
callback = function (err, stdout, stderr) {
if (err) throughStream.emit('error', err);
else stdout.pipe(throughStream);
}
}
if (format) {
format = format.split('.').pop();
this.outname = format + ":-";
}
var self = this;
this._preprocess(function (err) {
if (err) return callback(err);
return self._spawn(self.args(), false, callback);
});
return throughStream || this;
}
/**
* Convenience function for `proto.stream`.
* Simply returns the buffer instead of the stream.
*
* @param {String} format (optional)
* @param {Function} callback
* @return {null}
*/
proto.toBuffer = function toBuffer (format, callback) {
if (!callback) callback = format, format = null;
if ("function" !== typeof callback) {
throw new Error('gm().toBuffer() expects a callback.');
}
return this.stream(format, function (err, stdout) {
if (err) return callback(err);
streamToUnemptyBuffer(stdout, callback);
})
}
/**
* Run any preProcessor functions in series. Used by autoOrient.
*
* @param {Function} callback
* @return {Object} gm
*/
proto._preprocess = function _preprocess (callback) {
series(this._preprocessor, this, callback);
}
/**
* Execute the command, buffer input and output, return stdout and stderr buffers.
*
* @param {String} bin
* @param {Array} args
* @param {Function} callback
* @return {Object} gm
*/
proto._exec = function _exec (args, callback) {
return this._spawn(args, true, callback);
}
/**
* Execute the command with stdin, returning stdout and stderr streams or buffers.
* @param {String} bin
* @param {Array} args
* @param {ReadableStream} stream
* @param {Boolean} shouldBuffer
* @param {Function} callback, signature (err, stdout, stderr) -> *
* @return {Object} gm
* @TODO refactor this mess
*/
proto._spawn = function _spawn (args, bufferOutput, callback) {
var appPath = this._options.appPath || '';
var bin
// Resolve executable
switch (this._options.imageMagick) {
// legacy behavior
case true:
bin = args.shift();
break;
// ImgeMagick >= 7
case '7+':
bin = 'magick'
break;
// GraphicsMagick
default:
bin = 'gm';
break;
}
// Prepend app path
bin = appPath + bin
var cmd = bin + ' ' + args.map(utils.escape).join(' ')
, self = this
, proc, err
, timeout = parseInt(this._options.timeout)
, disposers = this._options.disposers
, timeoutId;
debug(cmd);
//imageMagick does not support minify (https://github.com/aheckmann/gm/issues/385)
if(args.indexOf("-minify") > -1 && this._options.imageMagick){
return cb(new Error("imageMagick does not support minify, use -scale or -sample. Alternatively, use graphicsMagick"));
}
try {
proc = spawn(bin, args);
} catch (e) {
return cb(e);
}
proc.stdin.once('error', cb);
proc.on('error', function(err){
if (err.code === 'ENOENT') {
cb(new Error('Could not execute GraphicsMagick/ImageMagick: '+cmd+" this most likely means the gm/convert binaries can't be found"));
} else {
cb(err);
}
});
if (timeout) {
timeoutId = setTimeout(function(){
dispose('gm() resulted in a timeout.');
}, timeout);
}
if (disposers) {
disposers.forEach(function(disposer) {
disposer.events.forEach(function(event) {
disposer.emitter.on(event, dispose);
});
});
}
if (self.sourceBuffer) {
proc.stdin.write(this.sourceBuffer);
proc.stdin.end();
} else if (self.sourceStream) {
if (!self.sourceStream.readable) {
return cb(new Error("gm().stream() or gm().write() with a non-readable stream."));
}
self.sourceStream.pipe(proc.stdin);
// bufferStream
// We convert the input source from a stream to a buffer.
if (self.bufferStream && !this._buffering) {
if (!Buffer.concat) {
throw new Error(noBufferConcat);
}
// Incase there are multiple processes in parallel,
// we only need one
self._buffering = true;
streamToUnemptyBuffer(self.sourceStream, function (err, buffer) {
self.sourceBuffer = buffer;
self.sourceStream = null; // The stream is now dead
})
}
}
// for _exec operations (identify() mostly), we also
// need to buffer the output stream before returning
if (bufferOutput) {
var stdout = ''
, stderr = ''
, onOut
, onErr
, onExit
proc.stdout.on('data', onOut = function (data) {
stdout += data;
});
proc.stderr.on('data', onErr = function (data) {
stderr += data;
});
proc.on('close', onExit = function (code, signal) {
let err;
if (code !== 0 || signal !== null) {
err = new Error('Command failed: ' + stderr);
err.code = code;
err.signal = signal;
};
cb(err, stdout, stderr, cmd);
stdout = stderr = onOut = onErr = onExit = null;
});
} else {
cb(null, proc.stdout, proc.stderr, cmd);
}
return self;
function cb (err, stdout, stderr, cmd) {
if (cb.called) return;
if (timeoutId) clearTimeout(timeoutId);
cb.called = 1;
if (args[0] !== 'identify' && bin !== 'identify') {
self._in = [];
self._out = [];
}
callback.call(self, err, stdout, stderr, cmd);
}
function dispose (msg) {
const message = msg ? msg : 'gm() was disposed';
const err = new Error(message);
cb(err);
if (proc.exitCode === null) {
proc.stdin.pause();
proc.kill();
}
}
}
/**
* Returns arguments to be used in the command.
*
* @return {Array}
*/
proto.args = function args () {
var outname = this.outname || "-";
if (this._outputFormat) outname = this._outputFormat + ':' + outname;
return [].concat(
this._subCommand
, this._in
, this.src()
, this._out
, outname
).filter(Boolean); // remove falsey
}
/**
* Adds an img source formatter.
*
* `formatters` are passed an array of images which will be
* used as 'input' images for the command. Useful for methods
* like `.append()` where multiple source images may be used.
*
* @param {Function} formatter
* @return {gm} this
*/
proto.addSrcFormatter = function addSrcFormatter (formatter) {
if ('function' != typeof formatter)
throw new TypeError('sourceFormatter must be a function');
this._sourceFormatters || (this._sourceFormatters = []);
this._sourceFormatters.push(formatter);
return this;
}
/**
* Applies all _sourceFormatters
*
* @return {Array}
*/
proto.src = function src () {
var arr = [];
for (var i = 0; i < this._sourceFormatters.length; ++i) {
this._sourceFormatters[i].call(this, arr);
}
return arr;
}
/**
* Image types.
*/
var types = {
'jpg': /\.jpe?g$/i
, 'png' : /\.png$/i
, 'gif' : /\.gif$/i
, 'tiff': /\.tif?f$/i
, 'bmp' : /(?:\.bmp|\.dib)$/i
, 'webp': /\.webp$/i
};
types.jpeg = types.jpg;
types.tif = types.tiff;
types.dib = types.bmp;
/**
* Determine the type of source image.
*
* @param {String} type
* @return {Boolean}
* @example
* if (this.inputIs('png')) ...
*/
proto.inputIs = function inputIs (type) {
if (!type) return false;
var rgx = types[type];
if (!rgx) {
if ('.' !== type[0]) type = '.' + type;
rgx = new RegExp('\\' + type + '$', 'i');
}
return rgx.test(this.source);
}
/**
* add disposer (like 'close' of http.IncomingMessage) in order to dispose gm() with any event
*
* @param {EventEmitter} emitter
* @param {Array} events
* @return {Object} gm
* @example
* command.addDisposer(req, ['close', 'end', 'finish']);
*/
proto.addDisposer = function addDisposer (emitter, events) {
if (!this._options.disposers) {
this._options.disposers = [];
}
this._options.disposers.push({
emitter: emitter,
events: events
});
return this;
};
}
================================================
FILE: lib/compare.js
================================================
// compare
var spawn = require('cross-spawn');
var debug = require('debug')('gm');
var utils = require('./utils');
/**
* Compare two images uses graphicsmagicks `compare` command.
*
* gm.compare(img1, img2, 0.4, function (err, equal, equality) {
* if (err) return handle(err);
* console.log('The images are equal: %s', equal);
* console.log('There equality was %d', equality);
* });
*
* @param {String} orig Path to an image.
* @param {String} compareTo Path to another image to compare to `orig`.
* @param {Number|Object} [options] Options object or the amount of difference to tolerate before failing - defaults to 0.4
* @param {Function} cb(err, Boolean, equality, rawOutput)
*/
module.exports = exports = function (proto) {
function compare(orig, compareTo, options, cb) {
var isImageMagick = this._options && this._options.imageMagick;
var appPath = this._options && this._options.appPath || '';
var args = ['-metric', 'mse', orig, compareTo];
// Resove executable
let bin;
switch (isImageMagick) {
case true:
bin = 'compare';
break;
case '7+':
bin = 'magick'
args.unshift('compare');
break;
default:
bin = 'gm'
args.unshift('compare');
break
}
// Prepend app path
bin = appPath + bin
var tolerance = 0.4;
// outputting the diff image
if (typeof options === 'object') {
if (options.highlightColor && options.highlightColor.indexOf('"') < 0) {
options.highlightColor = '"' + options.highlightColor + '"';
}
if (options.file) {
if (typeof options.file !== 'string') {
throw new TypeError('The path for the diff output is invalid');
}
// graphicsmagick defaults to red
if (options.highlightColor) {
args.push('-highlight-color');
args.push(options.highlightColor);
}
if (options.highlightStyle) {
args.push('-highlight-style')
args.push(options.highlightStyle)
}
// For IM, filename is the last argument. For GM it's `-file <filename>`
if (!isImageMagick) {
args.push('-file');
}
args.push(options.file);
}
if (typeof options.tolerance != 'undefined') {
if (typeof options.tolerance !== 'number') {
throw new TypeError('The tolerance value should be a number');
}
tolerance = options.tolerance;
}
} else {
// For ImageMagick diff file is required but we don't care about it, so null it out
if (isImageMagick) {
args.push('null:');
}
if (typeof options == 'function') {
cb = options; // tolerance value not provided, flip the cb place
} else {
tolerance = options
}
}
var cmd = bin + ' ' + args.map(utils.escape).join(' ')
debug(cmd);
var proc = spawn(bin, args);
var stdout = '';
var stderr = '';
proc.stdout.on('data',function(data) { stdout+=data });
proc.stderr.on('data',function(data) { stderr+=data });
proc.on('close', function (code) {
// ImageMagick returns err code 2 if err, 0 if similar, 1 if dissimilar
if (isImageMagick) {
if (code === 0) {
return cb(null, 0 <= tolerance, 0, stdout);
}
else if (code === 1) {
stdout = stderr;
} else {
return cb(stderr);
}
} else {
if(code !== 0) {
return cb(stderr);
}
}
// Since ImageMagick similar gives err code 0 and no stdout, there's really no matching
// Otherwise, output format for IM is `12.00 (0.123)` and for GM it's `Total: 0.123`
var regex = isImageMagick ? /\((\d+\.?[\d\-\+e]*)\)/m : /Total: (\d+\.?\d*)/m;
var match = regex.exec(stdout);
if (!match) {
return cb(new Error('Unable to parse output.\nGot ' + stdout));
}
var equality = parseFloat(match[1]);
cb(null, equality <= tolerance, equality, stdout, orig, compareTo);
});
}
if (proto) {
proto.compare = compare;
}
return compare;
};
================================================
FILE: lib/composite.js
================================================
// composite
/**
* Composite images together using the `composite` command in graphicsmagick.
*
* 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.");
* });
*
* @param {String} other Path to the image that contains the changes.
* @param {String} [mask] Path to the image with opacity informtion. Grayscale.
*/
module.exports = exports = function(proto) {
proto.composite = function(other, mask) {
this.in(other);
// If the mask is defined, add it to the output.
if(typeof mask !== "undefined")
this.out(mask);
this.subCommand("composite");
return this;
}
}
================================================
FILE: lib/convenience/autoOrient.js
================================================
/**
* Extend proto.
*/
module.exports = function (proto) {
var exifTransforms = {
topleft: ''
, topright: ['-flop']
, bottomright: ['-rotate', 180]
, bottomleft: ['-flip']
, lefttop: ['-flip', '-rotate', 90]
, righttop: ['-rotate', 90]
, rightbottom: ['-flop', '-rotate', 90]
, leftbottom: ['-rotate', 270]
}
proto.autoOrient = function autoOrient () {
// Always strip EXIF data since we can't
// change/edit it.
// imagemagick has a native -auto-orient option
// so does graphicsmagick, but in 1.3.18.
// nativeAutoOrient option enables this if you know you have >= 1.3.18
if (this._options.nativeAutoOrient || this._options.imageMagick) {
this.out('-auto-orient');
return this;
}
this.preprocessor(function (callback) {
this.orientation({bufferStream: true}, function (err, orientation) {
if (err) return callback(err);
var transforms = exifTransforms[orientation.toLowerCase()];
if (transforms) {
// remove any existing transforms that might conflict
var index = this._out.indexOf(transforms[0]);
if (~index) {
this._out.splice(index, transforms.length);
}
// repage to fix coordinates
this._out.unshift.apply(this._out, transforms.concat('-page', '+0+0'));
}
callback();
});
});
return this;
}
}
================================================
FILE: lib/convenience/morph.js
================================================
/**
* Module dependencies.
*/
var fs = require('fs');
var parallel = require('array-parallel');
/**
* Extend proto.
*/
module.exports = function (proto) {
/**
* Do nothing.
*/
function noop () {}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-morph
proto.morph = function morph (other, outname, callback) {
if (!outname) {
throw new Error("an output filename is required");
}
callback = (callback || noop).bind(this)
var self = this;
if (Array.isArray(other)) {
other.forEach(function (img) {
self.out(img);
});
self.out("-morph", other.length);
} else {
self.out(other, "-morph", 1);
}
self.write(outname, function (err, stdout, stderr, cmd) {
if (err) return callback(err, stdout, stderr, cmd);
// Apparently some platforms create the following temporary files.
// Check if the output file exists, if it doesn't, then
// work with temporary files.
fs.exists(outname, function (exists) {
if (exists) return callback(null, stdout, stderr, cmd);
parallel([
fs.unlink.bind(fs, outname + '.0'),
fs.unlink.bind(fs, outname + '.2'),
fs.rename.bind(fs, outname + '.1', outname)
], function (err) {
callback(err, stdout, stderr, cmd);
})
})
});
return self;
}
}
================================================
FILE: lib/convenience/sepia.js
================================================
/**
* Extend proto.
*/
module.exports = function (proto) {
proto.sepia = function sepia () {
return this.modulate(115, 0, 100).colorize(7, 21, 50);
}
}
================================================
FILE: lib/convenience/thumb.js
================================================
/**
* Extend proto.
*/
module.exports = function (proto) {
proto.thumb = function thumb (w, h, name, quality, align, progressive, callback, opts) {
var self = this,
args = Array.prototype.slice.call(arguments);
opts = args.pop();
if (typeof opts === 'function') {
callback = opts;
opts = '';
} else {
callback = args.pop();
}
w = args.shift();
h = args.shift();
name = args.shift();
quality = args.shift() || 63;
align = args.shift() || 'topleft';
var interlace = args.shift() ? 'Line' : 'None';
self.size(function (err, size) {
if (err) {
return callback.apply(self, arguments);
}
w = parseInt(w, 10);
h = parseInt(h, 10);
var w1, h1;
var xoffset = 0;
var yoffset = 0;
if (size.width < size.height) {
w1 = w;
h1 = Math.floor(size.height * (w/size.width));
if (h1 < h) {
w1 = Math.floor(w1 * (((h-h1)/h) + 1));
h1 = h;
}
} else if (size.width > size.height) {
h1 = h;
w1 = Math.floor(size.width * (h/size.height));
if (w1 < w) {
h1 = Math.floor(h1 * (((w-w1)/w) + 1));
w1 = w;
}
} else if (size.width == size.height) {
var bigger = (w>h?w:h);
w1 = bigger;
h1 = bigger;
}
if (align == 'center') {
if (w < w1) {
xoffset = (w1-w)/2;
}
if (h < h1) {
yoffset = (h1-h)/2;
}
}
self
.quality(quality)
.in("-size", w1+"x"+h1)
.scale(w1, h1, opts)
.crop(w, h, xoffset, yoffset)
.interlace(interlace)
.noProfile()
.write(name, function () {
callback.apply(self, arguments);
});
});
return self;
};
proto.thumbExact = function () {
var self = this,
args = Array.prototype.slice.call(arguments);
args.push('!');
self.thumb.apply(self, args);
};
};
================================================
FILE: lib/convenience.js
================================================
/**
* Extend proto
*/
module.exports = function (proto) {
require("./convenience/thumb")(proto);
require("./convenience/morph")(proto);
require("./convenience/sepia")(proto);
require("./convenience/autoOrient")(proto);
}
================================================
FILE: lib/drawing.js
================================================
/**
* Module dependencies.
*/
var escape = require('./utils').escape;
/**
* Extend proto.
*/
module.exports = function (proto) {
// http://www.graphicsmagick.org/GraphicsMagick.html#details-fill
proto.fill = function fill (color) {
return this.out("-fill", color || "none");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-stroke
proto.stroke = function stroke (color, width) {
if (width) {
this.strokeWidth(width);
}
return this.out("-stroke", color || "none");
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-strokewidth
proto.strokeWidth = function strokeWidth (width) {
return this.out("-strokewidth", width);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-font
proto.font = function font (font, size) {
if (size) {
this.fontSize(size);
}
return this.out("-font", font);
}
// http://www.graphicsmagick.org/GraphicsMagick.html
proto.fontSize = function fontSize (size) {
return this.out("-pointsize", size);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.draw = function draw (args) {
return this.out("-draw", [].slice.call(arguments).join(" "));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawPoint = function drawPoint (x, y) {
return this.draw("point", x +","+ y);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawLine = function drawLine (x0, y0, x1, y1) {
return this.draw("line", x0+","+y0, x1+","+y1);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawRectangle = function drawRectangle (x0, y0, x1, y1, wc, hc) {
var shape = "rectangle"
, lastarg;
if ("undefined" !== typeof wc) {
shape = "roundRectangle";
if ("undefined" === typeof hc) {
hc = wc;
}
lastarg = wc+","+hc;
}
return this.draw(shape, x0+","+y0, x1+","+y1, lastarg);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawArc = function drawArc (x0, y0, x1, y1, a0, a1) {
return this.draw("arc", x0+","+y0, x1+","+y1, a0+","+a1);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawEllipse = function drawEllipse (x0, y0, rx, ry, a0, a1) {
if (a0 == undefined) a0 = 0;
if (a1 == undefined) a1 = 360;
return this.draw("ellipse", x0+","+y0, rx+","+ry, a0+","+a1);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawCircle = function drawCircle (x0, y0, x1, y1) {
return this.draw("circle", x0+","+y0, x1+","+y1);
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawPolyline = function drawPolyline () {
return this.draw("polyline", formatPoints(arguments));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawPolygon = function drawPolygon () {
return this.draw("polygon", formatPoints(arguments));
}
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawBezier = function drawBezier () {
return this.draw("bezier", formatPoints(arguments));
}
proto._gravities = [
"northwest"
, "north"
, "northeast"
, "west"
, "center"
, "east"
, "southwest"
, "south"
, "southeast"];
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.drawText = function drawText (x0, y0, text, gravity) {
var gravity = String(gravity || "").toLowerCase()
, arg = ["text " + x0 + "," + y0 + " " + escape(text)];
if (~this._gravities.indexOf(gravity)) {
arg.unshift("gravity", gravity);
}
return this.draw.apply(this, arg);
}
proto._drawProps = ["color", "matte"];
// http://www.graphicsmagick.org/GraphicsMagick.html#details-draw
proto.setDraw = function setDraw (prop, x, y, method) {
prop = String(prop || "").toLowerCase();
if (!~this._drawProps.indexOf(prop)) {
return this;
}
return this.draw(prop, x+","+y, method);
}
}
function formatPoints (points) {
var len = points.length
, result = []
, i = 0;
for (; i < len; ++i) {
result.push(points[i].join(","));
}
return result;
}
================================================
FILE: lib/getters.js
================================================
/**
* Extend proto.
*/
module.exports = function (gm) {
var proto = gm.prototype;
/**
* `identify` states
*/
const IDENTIFYING = 1;
const IDENTIFIED = 2;
/**
* Map getter functions to output names.
*
* - format: specifying the -format argument (see man gm)
* - verbose: use -verbose instead of -format (only if necessary b/c its slow)
* - helper: use the conversion helper
*/
var map = {
'format': { key: 'format', format: '%m ', helper: 'Format' }
, 'depth': { key: 'depth', format: '%q' }
, 'filesize': { key: 'Filesize', format: '%b' }
, 'size': { key: 'size', format: '%wx%h ', helper: 'Geometry' }
, 'color': { key: 'color', format: '%k', helper: 'Colors' }
, 'orientation': { key: 'Orientation', format: '%[EXIF:Orientation]', helper: 'Orientation' }
, 'res': { key: 'Resolution', verbose: true }
}
/**
* Getter functions
*/
Object.keys(map).forEach(function (getter) {
proto[getter] = function (opts, callback) {
if (!callback) callback = opts, opts = {};
if (!callback) return this;
var val = map[getter]
, key = val.key
, self = this;
if (self.data[key]) {
callback.call(self, null, self.data[key]);
return self;
}
self.on(getter, callback);
self.bufferStream = !!opts.bufferStream;
if (val.verbose) {
self.identify(opts, function (err, stdout, stderr, cmd) {
if (err) {
self.emit(getter, err, self.data[key], stdout, stderr, cmd);
} else {
self.emit(getter, err, self.data[key]);
}
});
return self;
}
var args = makeArgs(self, val);
self._exec(args, function (err, stdout, stderr, cmd) {
if (err) {
self.emit(getter, err, self.data[key], stdout, stderr, cmd);
return;
}
var result = (stdout||'').trim();
if (val.helper in helper) {
helper[val.helper](self.data, result);
} else {
self.data[key] = result;
}
self.emit(getter, err, self.data[key]);
});
return self;
}
});
/**
* identify command
*
* Overwrites all internal data with the parsed output
* which is more accurate than the fast shortcut
* getters.
*/
proto.identify = function identify (opts, callback) {
// identify with pattern
if (typeof(opts) === 'string') {
opts = {
format: opts
}
}
if (!callback) callback = opts, opts = {};
if (!callback) return this;
if (opts && opts.format) return identifyPattern.call(this, opts, callback);
var self = this;
if (IDENTIFIED === self._identifyState) {
callback.call(self, null, self.data);
return self;
}
self.on('identify', callback);
if (IDENTIFYING === self._identifyState) {
return self;
}
self._identifyState = IDENTIFYING;
self.bufferStream = !!opts.bufferStream;
var args = makeArgs(self, { verbose: true });
self._exec(args, function (err, stdout, stderr, cmd) {
if (err) {
self.emit('identify', err, self.data, stdout, stderr, cmd);
return;
}
err = parse(stdout, self);
if (err) {
self.emit('identify', err, self.data, stdout, stderr, cmd);
return;
}
self.data.path = self.source;
self.emit('identify', null, self.data);
self._identifyState = IDENTIFIED;
});
return self;
}
/**
* identify with pattern
*
* Execute `identify -format` with custom pattern
*/
function identifyPattern (opts, callback) {
var self = this;
self.bufferStream = !!opts.bufferStream;
var args = makeArgs(self, opts);
self._exec(args, function (err, stdout, stderr, cmd) {
if (err) {
return callback.call(self, err, undefined, stdout, stderr, cmd);
}
callback.call(self, err, (stdout||'').trim());
});
return self;
}
/**
* Parses `identify` responses.
*
* @param {String} stdout
* @param {Gm} self
* @return {Error} [optionally]
*/
function parse (stdout, self) {
// normalize
var parts = (stdout||"").trim().replace(/\r\n|\r/g, "\n").split("\n");
// skip the first line (its just the filename)
parts.shift();
try {
var len = parts.length
, rgx1 = /^( *)(.+?): (.*)$/ // key: val
, rgx2 = /^( *)(.+?):$/ // key: begin nested object
, out = { indent: {} }
, level = null
, lastkey
, i = 0
, res
, o
for (; i < len; ++i) {
res = rgx1.exec(parts[i]) || rgx2.exec(parts[i]);
if (!res) continue;
var indent = res[1].length
, key = res[2] ? res[2].trim() : '';
if ('Image' == key || 'Warning' == key) continue;
var val = res[3] ? res[3].trim() : null;
// first iteration?
if (null === level) {
level = indent;
o = out.root = out.indent[level] = self.data;
} else if (indent < level) {
// outdent
if (!(indent in out.indent)) {
continue;
}
o = out.indent[indent];
} else if (indent > level) {
// dropping into a nested object
out.indent[level] = o;
// weird format, key/val pair with nested children. discard the val
o = o[lastkey] = {};
}
level = indent;
if (val) {
// if previous key was exist and we got the same key
// cast it to an array.
if(o.hasOwnProperty(key)){
// cast it to an array and dont forget the previous value
if(!Array.isArray(o[key])){
var tmp = o[key];
o[key] = [tmp];
}
// set value
o[key].push(val);
} else {
o[key] = val;
}
if (key in helper) {
helper[key](o, val);
}
}
lastkey = key;
}
} catch (err) {
err.message = err.message + "\n\n Identify stdout:\n " + stdout;
return err;
}
}
/**
* Create an argument array for the identify command.
*
* @param {gm} self
* @param {Object} val
* @return {Array}
*/
function makeArgs (self, val) {
var args = [
'identify'
, '-ping'
];
if (val.format) {
args.push('-format', val.format);
}
if (val.verbose) {
args.push('-verbose');
}
args = args.concat(self.src());
return args;
}
/**
* Map exif orientation codes to orientation names.
*/
var orientations = {
'1': 'TopLeft'
, '2': 'TopRight'
, '3': 'BottomRight'
, '4': 'BottomLeft'
, '5': 'LeftTop'
, '6': 'RightTop'
, '7': 'RightBottom'
, '8': 'LeftBottom'
}
/**
* identify -verbose helpers
*/
var helper = gm.identifyHelpers = {};
helper.Geometry = function Geometry (o, val) {
// We only want the size of the first frame.
// Each frame is separated by a space.
var split = val.split(" ").shift().split("x");
var width = parseInt(split[0], 10);
var height = parseInt(split[1], 10);
if (o.size && o.size.width && o.size.height) {
if (width > o.size.width) o.size.width = width;
if (height > o.size.height) o.size.height = height;
} else {
o.size = {
width: width,
height: height
}
}
};
helper.Format = function Format (o, val) {
o.format = val.split(" ")[0];
};
helper.Depth = function Depth (o, val) {
o.depth = parseInt(val, 10);
};
helper.Colors = function Colors (o, val) {
o.color = parseInt(val, 10);
};
helper.Orientation = function Orientation (o, val) {
if (val in orientations) {
o['Profile-EXIF'] || (o['Profile-EXIF'] = {});
o['Profile-EXIF'].Orientation = val;
o.Orientation = orientations[val];
} else {
o.Orientation = val || 'Unknown';
}
};
}
================================================
FILE: lib/montage.js
================================================
// montage
/**
* Montage images next to each other using the `montage` command in graphicsmagick.
*
* 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.");
* });
*
* @param {String} other Path to the image that contains the changes.
*/
module.exports = exports = function(proto) {
proto.montage = function(other) {
this.in(other);
this.subCommand("montage");
return this;
}
}
================================================
FILE: lib/options.js
================================================
module.exports = exports = function (proto) {
proto._options = {};
proto.options = function setOptions (options) {
var keys = Object.keys(options)
, i = keys.length
, key
while (i--) {
key = keys[i];
this._options[key] = options[key];
}
return this;
}
}
================================================
FILE: lib/utils.js
================================================
/**
* Escape the given shell `arg`.
*
* @param {String} arg
* @return {String}
* @api public
*/
exports.escape = function escape (arg) {
return '"' + String(arg).trim().replace(/"/g, '\\"') + '"';
};
exports.unescape = function escape (arg) {
return String(arg).trim().replace(/"/g, "");
};
exports.argsToArray = function (args) {
var arr = [];
for (var i = 0; i <= arguments.length; i++) {
if ('undefined' != typeof arguments[i])
arr.push(arguments[i]);
}
return arr;
};
exports.isUtil = function (v) {
var ty = 'object';
switch (Object.prototype.toString.call(v)) {
case '[object String]':
ty = 'String';
break;
case '[object Array]':
ty = 'Array';
break;
case '[object Boolean]':
ty = 'Boolean';
break;
}
return ty;
}
================================================
FILE: package.json
================================================
{
"name": "gm",
"description": "GraphicsMagick and ImageMagick for node.js",
"version": "1.25.1",
"author": "Aaron Heckmann <aaron.heckmann+github@gmail.com>",
"keywords": [
"graphics",
"magick",
"image",
"graphicsmagick",
"imagemagick",
"gm",
"convert",
"identify",
"compare"
],
"engines": {
"node": ">=14"
},
"bugs": {
"url": "http://github.com/aheckmann/gm/issues"
},
"licenses": [
{
"type": "MIT",
"url": "http://www.opensource.org/licenses/mit-license.php"
}
],
"main": "./index",
"scripts": {
"security": "npm audit",
"test": "npm run security && npm run test-integration",
"test-integration": "node test/ --integration",
"test-unit": "node test/"
},
"repository": {
"type": "git",
"url": "https://github.com/aheckmann/gm.git"
},
"license": "MIT",
"devDependencies": {
"async": "~0.9.0"
},
"dependencies": {
"array-parallel": "~0.1.3",
"array-series": "~0.1.5",
"cross-spawn": "^7.0.5",
"debug": "^3.1.0"
}
}
================================================
FILE: test/109.js
================================================
const fs = require('fs');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration) return finish();
const original = path.join(dir, 'original.jpg');
const buf = fs.readFileSync(original);
const m = gm(buf, 'original.jpg').options({ imageMagick });
m.identify(function (err, _) {
finish(err);
});
}
================================================
FILE: test/118.js
================================================
/*
* If only the width is specified for a resize operation,
* GraphicsMagick requires the format
* -resize 10x
* while ImageMagick requires the format
* -resize 10
*
*/
const assert = require('assert')
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration) return finish();
var src = path.join(dir, 'originalSideways.jpg');
var dst = path.join(dir, 'originalSideways10x.jpg');
gm(src).options({ imageMagick }).resize(10).write(dst, function(err) {
gm(dst).options({ imageMagick }).size(function(err, size) {
if (err) return finish(err);
assert.equal(10, size.width);
finish();
});
});
}
================================================
FILE: test/393.js
================================================
const assert = require('assert');
const fs = require('fs');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration) return finish();
var imagePath = path.join(__dirname, 'fixtures', 'nyancat.gif');
var inputStream = fs.createReadStream(imagePath);
gm(inputStream).options({ imageMagick }).identify({ bufferStream: true }, function(err, value) {
if (err) return finish(err);
var size = value.size;
assert.equal(400, size.width);
assert.equal(400, size.height);
finish();
});
}
================================================
FILE: test/417.js
================================================
const assert = require('assert')
const fs = require('fs');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration)
return finish();
const originalPathName = path.join(dir, 'original.jpg');
const thumbPathName = path.join(dir, 'thumb.png');
gm(originalPathName).options({ imageMagick }).thumb(150, 40, thumbPathName, function thumb (err) {
gm(thumbPathName).options({ imageMagick }).size(function (err, size) {
if (err) return finish(err);
assert.equal(142, size.width);
assert.equal(40, size.height);
gm(originalPathName).options({ imageMagick }).thumbExact(150, 40, thumbPathName, function thumb (err) {
gm(thumbPathName).options({ imageMagick }).size(function (err, size) {
assert.equal(150, size.width);
assert.equal(40, size.height);
finish(err);
});
});
});
});
}
================================================
FILE: test/422.js
================================================
const fs = require('fs');
const path = require('path');
module.exports = function (gm, dir, finish, GM, imageMagick) {
// Same image
const originalPathName = path.join(dir, 'original.jpg');
gm.compare(originalPathName, originalPathName, function(err, same, diff) {
if (err) return finish(err);
if (!same) {
const msg = `Compare should be the same! "${same}" "${diff}"`;
return finish(new Error(msg));
}
// Compare almost similar images for which ImageMagick
// returns an exponent-style floating point number
const compare1PathName = path.join(__dirname, 'fixtures', 'compare_1.png');
const compare2PathName = path.join(__dirname, 'fixtures', 'compare_2.png');
gm.compare(compare1PathName, compare2PathName, function(err, same, diff) {
if (err) return finish(err);
if (!same) {
const msg = `Compare should be the same! "${same}" "${diff}"`;
return finish(new Error(msg));
}
const noisePathName = path.join(dir, 'noise3.png');
// Create a new noisy image
gm.noise(0.3).write(noisePathName, function (err) {
if (err) return finish(err);
var options = {
highlightColor: '#fff',
file: path.join(dir, 'diff.png'),
tolerance: 0.001
};
const originalPathName = path.join(dir, 'original.jpg');
// Compare these images and write to a file.
gm.compare(originalPathName, noisePathName, options, function(err) {
if (err) return finish(err);
fs.access(options.file, fs.constants.F_OK, function(err) {
if (err) {
finish(new Error('Diff file does not exist.'));
} else {
fs.unlink(options.file, finish);
}
});
});
});
});
});
};
================================================
FILE: test/429.js
================================================
const fs = require('fs');
const path = require('path');
module.exports = function (gm, dir, finish, GM, imageMagick) {
if (!GM.integration) return finish();
const ico = path.join(__dirname, 'fixtures', 'test.ico');
const buffer = fs.readFileSync(ico);
const stream = fs.createReadStream(ico);
GM(ico).options({ imageMagick }).size(function (err) {
if (err) {
err.message = 'Failed using ico filename. ' + err.message;
return finish(err);
}
GM(buffer, 'img.ico').options({ imageMagick }).size(function (err) {
if (err) {
err.message = 'Failed using ico buffer. ' + err.message;
return finish(err);
}
GM(stream, 'img.ico').options({ imageMagick }).size({bufferStream: true}, function (err) {
if (err) {
err.message = 'Failed using ico stream. ' + err.message;
return finish(err);
}
finish();
});
});
});
}
================================================
FILE: test/68.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
var assert = require('assert')
var url = require('url')
var http = require('http')
module.exports = function (_, dir, finish, gm) {
return finish();
// use this test when gm is not installed.
// it demonstrates that err is often passed as null (timing)
// to detect the stream error that the gm command is not installed,
// you must test the stderr output manually for "execvp(): No such file or directory"
function done (err){
if (err) return finish(done.ran = err);
if (done.ran) return;
finish();
}
http.get(url.parse('http://www.google.com/images/srpr/logo3w.png'), function (resp) {
gm(resp, 'logo3w.png').stream(function (err, stdout, stderr) {
return finish();
if (err) {
console.error('Error processing image', err)
} else {
stdout.on('data', function (chunk) {
console.log('Chunk recieved', chunk.toString())
})
stdout.on('end', function () {
console.log('Stream ended')
})
stderr.on('data', function (chunk) {
console.log('err Chunk recieved', chunk.toString())
})
stderr.on('end', function () {
console.log('err Stream ended')
})
}
})
})
.on('error', function (err) {
console.error('Error fetching image', err)
})
}
================================================
FILE: test/70.js
================================================
const assert = require('assert')
const path = require('path');
var times = 16;
var loading = path.join(__dirname, 'fixtures', 'loading.gif');
var favicon = path.join(__dirname, 'fixtures', 'favicon.png');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration) return finish();
var pending = times/2;
var res = {};
res[loading] = {};
res[favicon] = {};
function done (err){
if (err) return finish(done.ran = err);
if (done.ran) return;
if (--pending) return;
finish();
}
new Array(times).join('x').split('x').forEach(function (_, i) {
;[loading, favicon].forEach(function (img) {
gm(img).options({imageMagick}).size(function (err, size) {
if (err) return done(err);
'width height'.split(' ').forEach(function (prop) {
if (!(prop in res[img])) {
res[img][prop] = size[prop];
} else {
assert.equal(res[img][prop], size[prop]);
}
});
done(err);
});
});
});
}
================================================
FILE: test/78.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration) return finish();
var name = imageMagick ? '78-IM' : '78';
var out = path.join(dir, name);
_.resize(600, 450, '!').write(out + '.png', function (err) {
if (err) return finish(err);
var img = gm(out + '.png').options({ imageMagick });
img
.crop(70, 70, 100, 100)
.resize(50, 50)
.write(out + '-2.jpg', function (err) {
if (err) return finish(err);
finish();
})
});
}
================================================
FILE: test/alpha.js
================================================
const assert = require('assert');
const Async = require('async');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration) return finish();
var alphaTypes = [
"Activate",
"On",
"Deactivate",
"Off",
"Set",
"Opaque",
"Transparent",
"Extract",
"Copy",
"Shape",
"Background"
];
const edgePath = path.join(dir, 'original.png');
const failPath = path.join(dir, 'alpha_fail.png');
// alpha not supported by GM so only test IM
if (!imageMagick) {
assert.throws(function() {
gm(edgePath)
.alpha(alphaTypes.pop())
.write(failPath);
});
finish();
} else {
Async.eachSeries(alphaTypes, function(alphaType, cb) {
var m = gm(edgePath).options({imageMagick}).alpha( alphaType );
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-alpha', args[2]);
assert.equal(alphaType, args[3]);
const writePath = path.join(dir, `alpha_${alphaType}.png`);
m.write(writePath, cb);
}, finish);
}
}
================================================
FILE: test/append.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
const out = path.resolve(dir, 'append.jpg');
const lostPath = path.join(dir, 'lost.png');
const originalPath = path.join(dir, 'original.jpg');
try {
require('fs').unlinkSync(out);
} catch (_) {}
var m = gm(lostPath)
.options({imageMagick})
.append(originalPath, originalPath)
.append()
.background('#222')
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-background',args[1]);
assert.equal('#222',args[2]);
assert.ok(/lost\.png$/.test(args[3]));
assert.ok(/original\.jpg$/,args[4]);
assert.ok(/original\.jpg$/,args[5]);
assert.equal('-append',args[6]);
assert.equal('-',args[7]);
if (!gm.integration) {
return horizontal({ dir, finish, gm, originalPath, lostPath, imageMagick });
}
m.write(out, function (err) {
if (err) return finish(err);
gm(out)
.options({imageMagick})
.size(function (err, size) {
if (err) return finish(err);
assert.equal(460, size.width);
assert.equal(435, size.height);
horizontal({ dir, finish, gm, originalPath, lostPath, imageMagick });
})
});
}
function horizontal ({ dir, finish, gm, originalPath, lostPath, imageMagick }) {
var out = path.resolve(dir, 'appendHorizontal.jpg');
var m = gm(originalPath).append(lostPath, true).options({imageMagick});
var args = m.args();
assert.equal('convert', args[0]);
assert.ok(/original\.jpg$/.test(args[1]));
assert.ok(/lost\.png$/.test(args[2]));
assert.equal('+append',args[3]);
assert.equal('-',args[4]);
if (!gm.integration) {
return finish();
}
m.write(out, function (err) {
if (err) return finish(err);
gm(out).options({imageMagick}).size(function (err, size) {
if (err) return finish(err);
assert.equal(697, size.width);
assert.equal(155, size.height);
finish();
})
});
}
================================================
FILE: test/arc.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.blur(8, 4)
.stroke("red", 3)
.fill("#ffffffbb")
.drawArc(80, 10, 90, 20, 0, 180)
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-blur', args[2]);
assert.equal('8x4', args[3]);
assert.equal('-strokewidth', args[4]);
assert.equal(3, args[5]);
assert.equal('-stroke', args[6]);
assert.equal('red', args[7]);
assert.equal('-fill', args[8]);
assert.equal('#ffffffbb', args[9]);
assert.equal('-draw', args[10]);
assert.equal('arc 80,10 90,20 0,180', args[11]);
if (!GM.integration) return finish();
const arcPath = path.join(dir, 'arc.png');
m.write(arcPath, function arc (err) {
finish(err);
});
}
================================================
FILE: test/autoOrient.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration)
return finish();
const sidewaysPath = path.join(dir, 'originalSideways.jpg');
gm(sidewaysPath)
.options({imageMagick})
.identify(function (err, o) {
if (err) return finish(err);
const geo = imageMagick ? '155x460+0+0' : '155x460';
assert.equal(geo, o.Geometry);
// this image is sideways, but may be auto-oriented by modern OS's
// try opening it in a browser to see its true orientation
gm(sidewaysPath)
.options({imageMagick})
.autoOrient()
.stream(function (err, stream) {
if (err) return finish(err);
gm(stream)
.options({imageMagick})
.identify(function (err, data) {
if (err) return finish(err);
const geo2 = imageMagick ? '460x155+0+0' : '460x155';
assert.equal(geo2, data.Geometry);
finish(err);
})
})
});
}
================================================
FILE: test/autoOrientAll.js
================================================
const assert = require('assert');
const fs = require('fs');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration) return finish();
var beforeValues = {
'Landscape_1.jpg': ['TopLeft', 1, '600x450'],
'Landscape_2.jpg': ['TopRight', 2, '600x450'],
'Landscape_3.jpg': ['BottomRight', 3, '600x450'],
'Landscape_4.jpg': ['BottomLeft', 4, '600x450'],
'Landscape_5.jpg': ['LeftTop', 5, '450x600'],
'Landscape_6.jpg': ['RightTop', 6, '450x600'],
'Landscape_7.jpg': ['RightBottom', 7, '450x600'],
'Landscape_8.jpg': ['LeftBottom', 8, '450x600'],
'Portrait_1.jpg': ['TopLeft', 1, '450x600'],
'Portrait_2.jpg': ['TopRight', 2, '450x600'],
'Portrait_3.jpg': ['BottomRight', 3, '450x600'],
'Portrait_4.jpg': ['BottomLeft', 4, '450x600'],
'Portrait_5.jpg': ['LeftTop', 5, '600x450'],
'Portrait_6.jpg': ['RightTop', 6, '600x450'],
'Portrait_7.jpg': ['RightBottom', 7, '600x450'],
'Portrait_8.jpg': ['LeftBottom', 8, '600x450']
};
var afterValues = {
'Landscape_1.jpg': '600x450',
'Landscape_2.jpg': '600x450',
'Landscape_3.jpg': '600x450',
'Landscape_4.jpg': '600x450',
'Landscape_5.jpg': '600x450',
'Landscape_6.jpg': '600x450',
'Landscape_7.jpg': '600x450',
'Landscape_8.jpg': '600x450',
'Portrait_1.jpg': '450x600',
'Portrait_2.jpg': '450x600',
'Portrait_3.jpg': '450x600',
'Portrait_4.jpg': '450x600',
'Portrait_5.jpg': '450x600',
'Portrait_6.jpg': '450x600',
'Portrait_7.jpg': '450x600',
'Portrait_8.jpg': '450x600'
};
const orientationDir = path.join(dir, 'orientation');
fs.readdir(orientationDir, function(err, files) {
if (err) return finish(err);
var originalFiles = files.filter(function(file) {
return beforeValues[file] && afterValues[file];
});
function next () {
test(originalFiles.pop());
}
return next();
function test (filename) {
if (!filename) return finish();
const fileToAutoOrient = path.join(orientationDir, filename);
const newFilename = fileToAutoOrient + '.oriented.jpg';
const constant = fileToAutoOrient + '.correct.jpg';
gm(fileToAutoOrient).options({imageMagick}).orientation(function (err, o) {
if (err) return finish(err);
assert.equal(beforeValues[filename][0], o);
assert.equal(beforeValues[filename][1], this.data['Profile-EXIF'].Orientation, 'No Profile-EXIF data found');
// this image is sideways, but may be auto-oriented by modern OS's
// try opening it in a browser to see its true orientation
gm(fileToAutoOrient)
.options({ imageMagick })
.autoOrient()
.write(newFilename, function autoOrient (err) {
if (err) return finish(err);
// fs race condition
setTimeout(function () {
gm(newFilename).options({ imageMagick }).identify(function (err) {
if (err) return finish(err);
const afterValue = imageMagick ? `${afterValues[filename]}+0+0` : afterValues[filename];
assert.equal(afterValue, this.data.Geometry, `Bad-Geometry for ${filename}. Got "${this.data.Geometry}"`);
gm().options({imageMagick}).compare(newFilename, constant, 0.1, function (err, equal) {
if (err) return finish(err);
assert.ok(equal);
next();
})
});
}, 200);
});
});
}
});
};
================================================
FILE: test/autoOrientAndThumb.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration)
return finish();
var original = path.join(dir, 'orientation', 'Portrait_7.jpg');
var result = path.join(dir, 'autoOrientAndThumb.png');
size(original, imageMagick, function (err, origSize) {
if (err) return finish(err);
assert.ok(origSize.width < 610);
assert.ok(origSize.height < 460);
gm(original)
.options({imageMagick})
.autoOrient()
.thumb(100, 100, result, function (err) {
if (err) return finish(err);
size(result, imageMagick, function (err, newSize) {
if (err) return finish(err);
assert.ok(newSize.width < 80);
assert.ok(newSize.height < 110);
finish();
});
});
});
function size (file, imageMagick, cb) {
gm(file).options({imageMagick}).identify(function (err, data) {
if (err) return cb(err);
cb(err, data.size);
});
}
}
================================================
FILE: test/autoOrientStream.js
================================================
// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
// This is a copy of `autoOrient.js` using streams
const assert = require('assert')
const fs = require('fs')
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration)
return finish();
const filename = path.join(dir, 'autoOrientStream.jpg');
const sidewaysPathName = path.join(dir, 'originalSideways.jpg');
gm(fs.createReadStream(sidewaysPathName)).options({imageMagick}).identify(function (err) {
if (err) return finish(err);
const geo = imageMagick ? '155x460+0+0' : '155x460';
assert.equal(geo, this.data.Geometry);
// this image is sideways, but may be auto-oriented by modern OS's
// try opening it in a browser to see its true orientation
gm(fs.createReadStream(sidewaysPathName))
.options({imageMagick})
.autoOrient()
.write(filename, function autoOrient (err) {
if (err) return finish(err);
// fs race condition
setTimeout(function () {
gm(filename).options({imageMagick}).identify(function (err) {
if (err) return finish(err);
const geo2 = imageMagick ? '460x155+0+0' : '460x155';
assert.equal(geo2, this.data.Geometry);
finish(err);
});
}, 200);
});
});
}
================================================
FILE: test/background.js
================================================
const assert =require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.crop(140,100)
.background("#FF0000")
.extent(340,300)
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-background', args[1]);
assert.equal('#FF0000', args[2]);
assert.equal('-crop', args[4]);
assert.equal('140x100+0+0', args[5]);
assert.equal('-extent', args[6]);
assert.equal('340x300', args[7]);
if (!GM.integration)
return finish();
const backgroundPathName = path.join(dir, 'background.jpg');
m.write(backgroundPathName, function (err) {
finish(err);
});
}
================================================
FILE: test/bezier.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.blur(8, 4)
.stroke("red", 3)
.fill("#ffffffbb")
.drawBezier([0, 10], [183, 163], [183, 10], [0, 10])
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-blur', args[2]);
assert.equal('8x4', args[3]);
assert.equal('-strokewidth', args[4]);
assert.equal(3, args[5]);
assert.equal('-stroke', args[6]);
assert.equal('red', args[7]);
assert.equal('-fill', args[8]);
assert.equal('#ffffffbb', args[9]);
assert.equal('-draw', args[10]);
assert.equal('bezier 0,10,183,163,183,10,0,10', args[11]);
if (!GM.integration)
return finish();
m
.write(path.join(dir, 'bezier.png'), function bezier (err) {
finish(err);
});
}
================================================
FILE: test/bitdepth.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.bitdepth(2);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-depth', args[2]);
assert.equal(2, args[3]);
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'bitdepth.png');
m.write(outpath, function bitdepth (err) {
finish(err);
});
}
================================================
FILE: test/blur.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.blur(18, 10);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-blur', args[2]);
assert.equal('18x10', args[3]);
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'blur.png');
m.write(outpath, function blur (err) {
finish(err);
});
}
================================================
FILE: test/changeFormat.js
================================================
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'changedformat.png');
gm.write(outpath, function changeformat (err) {
finish(err);
});
}
================================================
FILE: test/charcoal.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.charcoal(1);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-charcoal', args[2]);
assert.equal(1, args[3]);
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'charcoal.png');
m.write(outpath, function charcoal (err) {
finish(err);
});
}
================================================
FILE: test/chop.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.chop(54, 1, 307, 1);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-chop', args[1]);
assert.equal('54x1+307+1', args[2]);
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'chop.png');
m.write(outpath, function chop (err) {
finish(err);
});
}
================================================
FILE: test/circle.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.blur(8, 4)
.stroke("red", 1)
.fill("#ffffffbb")
.drawCircle(125, 45, 120, 5);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-blur', args[2]);
assert.equal('8x4', args[3]);
assert.equal('-strokewidth', args[4]);
assert.equal(1, args[5]);
assert.equal('-stroke', args[6]);
assert.equal('red', args[7]);
assert.equal('-fill', args[8]);
assert.equal('#ffffffbb', args[9]);
assert.equal('-draw', args[10]);
assert.equal('circle 125,45 120,5', args[11]);
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'circle.png');
m.write(outpath, function circle (err) {
finish(err);
});
}
================================================
FILE: test/colorize.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.colorize(80, 0, 30)
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-colorize', args[2]);
assert.equal('80,0,30', args[3]);
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'colorize.png');
m.write(outpath, function colorize (err) {
finish(err);
});
}
================================================
FILE: test/colors.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.colors(16);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-colors', args[2]);
assert.equal(16, args[3]);
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'colors.png');
m.write(outpath, function colors (err) {
finish(err);
});
}
================================================
FILE: test/comment.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.comment("%m:%f %wx%h");
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-comment', args[2]);
assert.equal('"%m:%f %wx%h"', args[3]);
if (!GM.integration)
return finish();
const outpath = path.join(dir, 'comment.png');
m.write(outpath, function comment (err) {
finish(err);
});
}
================================================
FILE: test/compare.js
================================================
const path = require('path');
const fs = require('fs');
module.exports = function (gm, dir, finish) {
// Same image
const originalJPGFilePath = path.join(dir, 'original.jpg');
const originalPNGFilePath = path.join(dir, 'original.png');
gm.compare(originalJPGFilePath, originalPNGFilePath, function(err, same) {
if (err) return finish(err);
if (!same) return finish(new Error('Compare should be the same!'));
// Compare almost similar images for which ImageMagick
// returns a exponent-style floating point number
const compare1Path = path.join(__dirname, 'fixtures', 'compare_1.png');
const compare2Path = path.join(__dirname, 'fixtures', 'compare_2.png');
gm.compare(compare1Path, compare2Path, function(err, same, diff) {
if (err) return finish(err);
if (!same) return finish(new Error('Compare should be the same!'));
// Create a new noisy image
const noisePath = path.join(dir, 'noise3.png');
gm.noise(0.3).write(noisePath, function (err) {
if (err) return finish(err);
const options = {
highlightColor: 'yellow',
file: path.join(dir, `compare-test-${Date.now()}.png`),
tolerance: 0.001
};
// Compare these images and write to a file.
gm.compare(originalJPGFilePath, noisePath, options, function(err) {
if (err) return finish(err);
fs.access(options.file, fs.constants.F_OK, function(err) {
if (err) {
finish(new Error('Diff file does not exist.'));
} else {
fs.unlink(options.file, () => finish());
}
});
});
});
});
});
};
================================================
FILE: test/composite.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
const sourcePath = path.join(__dirname, 'fixtures', 'compare_1.png');
gm.source = sourcePath;
const faviconPath = path.join(__dirname, 'fixtures', 'favicon.png');
const a = gm.composite(faviconPath)
const args = a.args();
assert.equal('composite', args[0]);
assert.equal(faviconPath, args[1]);
assert.equal(sourcePath, args[2]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'composite.png');
a.write(destPath, function(err) {
finish(err);
});
}
================================================
FILE: test/contrast.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
const m = gm.contrast(2);
const args = m.args();
assert.equal('convert', args[0]);
assert.equal('+contrast', args[2]);
assert.equal('+contrast', args[3]);
if (!GM.integration) return finish();
const destPath = path.join(dir, 'contrast.png');
m.write(destPath, function contrast (err) {
finish(err);
});
}
================================================
FILE: test/crop.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM, imageMagick) {
const m = gm.crop(200, 155, 300, 0);
const args = m.args();
assert.equal('convert', args[0]);
assert.equal('-crop', args[2]);
assert.equal('200x155+300+0', args[3]);
const imagePath = path.join(dir, 'image.png');
const m2 = GM(imagePath).options({ imageMagick }).crop(200, 155, 300, 0, true);
const args2 = m2.args();
assert.equal('200x155+300+0%', args2[3]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'crop.png');
m.write(destPath, function crop (err) {
finish(err);
});
}
================================================
FILE: test/cycle.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
const m = gm.cycle(4);
const args = m.args();
assert.equal('convert', args[0]);
assert.equal('-cycle', args[2]);
assert.equal(4, args[3]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'cycle.png');
m.write(destPath, function cycle (err) {
finish(err);
});
}
================================================
FILE: test/densityGm.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM, imageMagick) {
var NUMBER = 100;
var NUMBER2 = 200;
var g = gm.density(NUMBER, NUMBER2);
var gArgs = g.args();
assert.equal('convert', gArgs[0]);
assert.equal('-density', gArgs[1]);
assert.equal(NUMBER + 'x' + NUMBER2, gArgs[2]);
if (imageMagick) {
// graphicsmagick does not support density with two arguments
var imArgs = GM().options({imageMagick}).density(NUMBER).args();
assert.equal('convert', imArgs[0]);
assert.equal('-density', imArgs[1]);
assert.equal(NUMBER, imArgs[2]);
}
if (!GM.integration) return finish();
const destPath = path.join(dir, 'density.png');
g.write(destPath, function density (err) {
finish(err);
});
};
================================================
FILE: test/despeckle.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm.despeckle();
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-despeckle', args[2]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'despeckle.png');
m.write(destPath, function despeckle (err) {
finish(err);
});
}
================================================
FILE: test/dispose.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (img, dir, finish, gm, imageMagick) {
var EventEmitter = require('events').EventEmitter;
EventEmitter.prototype._maxListeners = 100;
assert.equal(undefined, gm.prototype._options.disposers);
assert.equal(undefined, img._options.disposers);
var emitter = new EventEmitter();
var disposer = {
emitter: emitter,
events: ['pleaseDispose', 'readyToDispose']
};
var g = gm('test').options({ disposers: [ disposer ], imageMagick });
assert.deepEqual([disposer], g._options.disposers);
var sub = gm.subClass({ disposers: [ disposer ], imageMagick });
assert.deepEqual([disposer], sub.prototype._options.disposers);
if (!gm.integration) {
return finish();
}
const photoPath = path.join(dir, 'photo.JPG');
const disposePath = path.join(dir, 'dispose.png');
gm(photoPath).options({ disposers: [ disposer ], imageMagick })
.thumb(1000, 1000, disposePath, function (err) {
assert.ok(err, "Expecting a disposed error");
});
emitter.emit('pleaseDispose');
noDispose();
function noDispose() {
gm(photoPath).options({ disposers: [ disposer ], imageMagick })
.thumb(1000, 1000, disposePath, function (err) {
finish(err);
});
emitter.emit('disposeOK');
}
}
================================================
FILE: test/dither.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
if (gm._options.imageMagick)
return finish();
var g = gm.monochrome().dither();
var args = g.args();
assert.equal('convert', args[0]);
assert.equal('-monochrome', args[2]);
assert.equal('-dither', args[3]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'dither.png');
g.write(destPath, function dither (err) {
finish(err);
});
}
================================================
FILE: test/edge.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.edge(2);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-edge', args[2]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'edge.png');
m.write(destPath, function edge (err) {
finish(err);
});
}
================================================
FILE: test/ellipse.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.blur(8, 4)
.stroke("blue", 1)
.drawEllipse(155, 80, 130, 50);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-blur', args[2]);
assert.equal('8x4', args[3]);
assert.equal('-strokewidth', args[4]);
assert.equal(1, args[5]);
assert.equal('-stroke', args[6]);
assert.equal('blue', args[7]);
assert.equal('-draw', args[8]);
assert.equal('ellipse 155,80 130,50 0,360', args[9]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'ellipse.png');
m.write(destPath, function ellipse (err) {
finish(err);
});
}
================================================
FILE: test/emboss.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.emboss(2);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-emboss', args[2]);
assert.equal(2, args[3]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'emboss.png');
m.write(destPath, function emboss (err) {
finish(err);
});
}
================================================
FILE: test/enhance.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.enhance();
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-enhance', args[2]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'enhance.png');
m.write(destPath, function enhance (err) {
finish(err);
});
}
================================================
FILE: test/equalize.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.equalize();
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-equalize', args[2]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'equalize.png');
m.write(destPath, function equalize (err) {
finish(err);
});
}
================================================
FILE: test/extent.js
================================================
const assert = require('assert')
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.scale(200, 100)
.extent(300,300)
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-scale', args[2]);
assert.equal('200x100', args[3]);
assert.equal('-extent', args[4]);
assert.equal('300x300', args[5]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'extent.png');
m.write(destPath, function resize (err) {
finish(err);
});
}
================================================
FILE: test/flatten.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
// graphicsmagick considers PSD broken
// http://www.graphicsmagick.org/NEWS.html#may-30-2016
if (!imageMagick) {
return finish();
}
const layersPath = path.join(dir, 'layers.psd');
var m = gm(layersPath)
.options({ imageMagick })
.flatten();
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-flatten', args[2]);
if (!gm.integration)
return finish();
const destPath = path.join(dir, 'unlayered.jpg');
m.write(destPath, function (err) {
finish(err);
});
}
================================================
FILE: test/flip.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.flip();
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-flip', args[2]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'flip.png');
m.write(destPath, function flip (err) {
finish(err);
});
}
================================================
FILE: test/flop.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.flop();
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-flop', args[2]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'flop.png');
m.write(destPath, function flop (err) {
finish(err);
});
}
================================================
FILE: test/fromBuffer.js
================================================
const assert = require('assert');
const path = require('path');
const fs = require('fs')
module.exports = function (_, dir, finish, gm, imageMagick) {
const original = path.join(dir, 'original.jpg');
const result = path.join(dir, 'fromBuffer.png');
var buf = fs.readFileSync(original);
var m = gm(buf).options({imageMagick}).rotate('red', 30);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-', args[1]);
assert.equal('-background', args[2]);
assert.equal('red', args[3]);
assert.equal('-rotate', args[4]);
assert.equal(30, args[5]);
if (!gm.integration)
return finish();
m.write(result, function crop (err) {
if (err) return finish(err);
// tolerance defaults to 0.4
m.compare(original, result, function (err, equal) {
if (err) return finish(err);
assert.ok(equal);
// accepts tolerance argument
m.compare(original, result, 0.1, function (err, equal, equality, raw) {
if (err) return finish(err);
assert.ok(!equal);
assert.ok(equality > 0.1);
assert.ok(raw);
finish();
})
})
});
}
================================================
FILE: test/gamma.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (gm, dir, finish, GM) {
var m = gm
.gamma(1.7, 2.3, 1.3);
var args = m.args();
assert.equal('convert', args[0]);
assert.equal('-gamma', args[2]);
assert.equal('1.7,2.3,1.3', args[3]);
if (!GM.integration)
return finish();
const destPath = path.join(dir, 'gamma.png');
m.write(destPath, function gamma (err) {
finish(err);
});
}
================================================
FILE: test/geometry.js
================================================
var assert = require('assert')
module.exports = function (_, __, finish, GM, imageMagick) {
var a = GM("dummy").options({imageMagick}).geometry("asdf"); // Custom geometry command
var args = a.args();
assert.equal('-geometry', args[2]);
assert.equal('asdf', args[3]);
var b = GM("dummy").options({imageMagick}).geometry("", 100);
var args = b.args();
assert.equal('-geometry', args[2]);
assert.equal('x100', args[3]); // Keep-aspect-ratio command
return finish();
}
================================================
FILE: test/getterColor.js
================================================
const assert = require('assert');
const path = require('path');
module.exports = function (_, dir, finish, gm, imageMagick) {
if (!gm.integration)
return finish();
const destPath = path.join(dir, 'blue.gif');
gm(destPath).options({imageMagick}).color(function (err, color) {
if (err) return finish(err);
assert.equal(1, color)
assert.equal(this.data.color, color)
finish();
});
}
================================================
FILE: test/getterDepth.js
================================================
var assert = require('assert')
module.exports = function (gm, dir, finish, GM) {
if (!GM.integration)
return finish();
gm
.depth(function getterdepth (err, depth) {
if (err) return finish(err);
if (this._options.imageMagick) {
assert.equal(16, depth);
assert.equal(16, this.data.depth);
} else {
assert.equal(8, depth);
assert.equal(8, this.data.depth);
}
finish();
});
}
================================================
FILE: test/getterFilesize.js
================================================
var assert = require('assert')
module.exports = function (gm, dir, finish, GM) {
if (!GM.integration)
return finish();
gm
.filesize(function getterfilesize (err, size) {
if (err) return finish(err);
if (this._options.imageMagick) {
assert.equal('7792B', size, size);
} else {
assert.ok(/7.6K[i]{0,
gitextract_x_d7l3ph/
├── .github/
│ └── workflows/
│ └── node.js.yml
├── .gitignore
├── .npmignore
├── History.md
├── README.md
├── examples/
│ ├── append.js
│ ├── background.js
│ ├── bitdepth.js
│ ├── blur.js
│ ├── changeFormat.js
│ ├── charcoal.js
│ ├── chop.js
│ ├── colorize.js
│ ├── colors.js
│ ├── comment.js
│ ├── compare.js
│ ├── contrast.js
│ ├── crop.js
│ ├── cycle.js
│ ├── despeckle.js
│ ├── dither.js
│ ├── drawing.js
│ ├── edge.js
│ ├── emboss.js
│ ├── enhance.js
│ ├── equalize.js
│ ├── extent.js
│ ├── flatten.js
│ ├── flip.js
│ ├── flop.js
│ ├── gamma.js
│ ├── getters.js
│ ├── gravity.js
│ ├── implode.js
│ ├── label.js
│ ├── limit.js
│ ├── lower.js
│ ├── magnify.js
│ ├── median.js
│ ├── minify.js
│ ├── modulate.js
│ ├── monochrome.js
│ ├── morph.js
│ ├── negative.js
│ ├── new.js
│ ├── noise1.js
│ ├── noise2.js
│ ├── paint.js
│ ├── quality.js
│ ├── raise.js
│ ├── region.js
│ ├── resample.js
│ ├── resize.js
│ ├── roll.js
│ ├── rotate.js
│ ├── scale.js
│ ├── sepia.js
│ ├── sharpen.js
│ ├── size.js
│ ├── solarize.js
│ ├── source_buffer.js
│ ├── spread.js
│ ├── swirl.js
│ ├── thumb.js
│ ├── thumbExact.js
│ └── thumbnail.js
├── index.js
├── lib/
│ ├── args.js
│ ├── command.js
│ ├── compare.js
│ ├── composite.js
│ ├── convenience/
│ │ ├── autoOrient.js
│ │ ├── morph.js
│ │ ├── sepia.js
│ │ └── thumb.js
│ ├── convenience.js
│ ├── drawing.js
│ ├── getters.js
│ ├── montage.js
│ ├── options.js
│ └── utils.js
├── package.json
└── test/
├── 109.js
├── 118.js
├── 393.js
├── 417.js
├── 422.js
├── 429.js
├── 68.js
├── 70.js
├── 78.js
├── alpha.js
├── append.js
├── arc.js
├── autoOrient.js
├── autoOrientAll.js
├── autoOrientAndThumb.js
├── autoOrientStream.js
├── background.js
├── bezier.js
├── bitdepth.js
├── blur.js
├── changeFormat.js
├── charcoal.js
├── chop.js
├── circle.js
├── colorize.js
├── colors.js
├── comment.js
├── compare.js
├── composite.js
├── contrast.js
├── crop.js
├── cycle.js
├── densityGm.js
├── despeckle.js
├── dispose.js
├── dither.js
├── edge.js
├── ellipse.js
├── emboss.js
├── enhance.js
├── equalize.js
├── extent.js
├── flatten.js
├── flip.js
├── flop.js
├── fromBuffer.js
├── gamma.js
├── geometry.js
├── getterColor.js
├── getterDepth.js
├── getterFilesize.js
├── getterFormat.js
├── getterFormatGIF.js
├── getterIdentify.js
├── getterIptc.js
├── getterMultipleIptc.js
├── getterRes.js
├── getterSize.js
├── gh-17.js
├── gifFrame.js
├── gifFrameIdentify.js
├── gifFrameStream.js
├── gravity.js
├── implode.js
├── index.js
├── inputIs.js
├── interlace.js
├── label.js
├── limit.js
├── line.js
├── lower.js
├── magnify.js
├── median.js
├── minify.js
├── minifyIM.js
├── modulate.js
├── monochrome.js
├── montage.js
├── morph-more.js
├── morph.js
├── negative.js
├── new.js
├── newImage.js
├── noise1.js
├── noise2.js
├── options.js
├── paint.js
├── polygon.js
├── polyline.js
├── quality.js
├── raise.js
├── rectangle.js
├── region.js
├── repagePlus.js
├── resample.js
├── resize.js
├── resizeAndAutoOrientFromBuffer.js
├── resizeBuffer.js
├── resizeWrong.js
├── roll.js
├── rotate.js
├── scale.js
├── selectFrame.js
├── sepia.js
├── setFormat.js
├── sharpen.js
├── solarize.js
├── spread.js
├── streamIn.js
├── streamInGetter.js
├── streamInOut.js
├── streamOut.js
├── streamOutFormat.js
├── strip.js
├── subclass.js
├── swirl.js
├── text.js
├── thumb.js
├── thumbnail.js
├── timeout.js
├── toBuffer.js
├── toBufferFormat.js
├── utils.js
└── webp.js
SYMBOL INDEX (42 symbols across 23 files)
FILE: index.js
function gm (line 20) | function gm (source, height, color) {
function gm (line 98) | function gm (source, height, color) {
FILE: lib/args.js
function comment (line 1112) | function comment (arg) {
FILE: lib/command.js
function args (line 24) | function args (prop) {
function streamToUnemptyBuffer (line 39) | function streamToUnemptyBuffer(stream, callback) {
function cb (line 331) | function cb (err, stdout, stderr, cmd) {
function dispose (line 342) | function dispose (msg) {
FILE: lib/compare.js
function compare (line 23) | function compare(orig, compareTo, options, cb) {
FILE: lib/convenience/morph.js
function noop (line 19) | function noop () {}
FILE: lib/drawing.js
function formatPoints (line 150) | function formatPoints (points) {
FILE: lib/getters.js
function identifyPattern (line 156) | function identifyPattern (opts, callback) {
function parse (line 182) | function parse (stdout, self) {
function makeArgs (line 268) | function makeArgs (self, val) {
FILE: test/68.js
function done (line 15) | function done (err){
FILE: test/70.js
function done (line 18) | function done (err){
FILE: test/append.js
function horizontal (line 47) | function horizontal ({ dir, finish, gm, originalPath, lostPath, imageMag...
FILE: test/autoOrientAll.js
function next (line 55) | function next () {
function test (line 61) | function test (filename) {
FILE: test/autoOrientAndThumb.js
function size (line 33) | function size (file, imageMagick, cb) {
FILE: test/dispose.js
function noDispose (line 40) | function noDispose() {
FILE: test/getterIdentify.js
function gif (line 65) | function gif (callback) {
function pattern (line 101) | function pattern () {
FILE: test/getterSize.js
function sizeJPEG (line 18) | function sizeJPEG(done) {
function sizeGIF (line 31) | function sizeGIF(done) {
function sizePNG (line 43) | function sizePNG(done) {
FILE: test/index.js
function filter (line 18) | function filter (file) {
function test (line 30) | function test (imageMagick) {
function finish (line 34) | function finish (filename) {
function isGraphicsMagickInstalled (line 43) | function isGraphicsMagickInstalled() {
function isConvertInstalled (line 52) | function isConvertInstalled() {
function isMagickInstalled (line 61) | function isMagickInstalled() {
FILE: test/newImage.js
function createImage (line 25) | function createImage() {
FILE: test/resizeAndAutoOrientFromBuffer.js
function size (line 43) | function size (file, imageMagick, cb) {
FILE: test/resizeBuffer.js
function size (line 46) | function size (file, imageMagick, cb) {
FILE: test/streamOut.js
function withCallback (line 15) | function withCallback(done) {
function withoutCallback (line 26) | function withoutCallback(done) {
FILE: test/streamOutFormat.js
function withCallback (line 19) | function withCallback(done) {
function withoutCallback (line 30) | function withoutCallback(done) {
function checkOutputFormat (line 38) | function checkOutputFormat(done) {
FILE: test/timeout.js
function noTimeout (line 28) | function noTimeout() {
FILE: test/webp.js
function write (line 26) | function write(done) {
function stream (line 42) | function stream(done) {
Condensed preview — 206 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (255K chars).
[
{
"path": ".github/workflows/node.js.yml",
"chars": 1422,
"preview": "# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tes"
},
{
"path": ".gitignore",
"chars": 317,
"preview": ".DS_Store\nnode_modules\npackage-lock.json\nexamples/imgs/*\n!examples/imgs/original.jpg\n!examples/imgs/original.png\n!exampl"
},
{
"path": ".npmignore",
"chars": 16,
"preview": "test/\nexamples/\n"
},
{
"path": "History.md",
"chars": 17103,
"preview": "1.25.1 / 2025-02-24\n\n* deps: bump cross-spawn [talyuk](https://github.com/talyuk)\n\n1.25.0 / 2022-09-21\n\n* fixed: windows"
},
{
"path": "README.md",
"chars": 27946,
"preview": "# 2025-02-24 This project is not maintained\n\nInstead of using this project, execute the `gm` or `magick` binaries using\n"
},
{
"path": "examples/append.js",
"chars": 431,
"preview": "var gm = require('../')\n , dir = __dirname + '/imgs'\n , imgs = 'lost.png original.jpg'.split(' ').map(function (img) {"
},
{
"path": "examples/background.js",
"chars": 305,
"preview": "var gm = require('../')\n , dir = __dirname + '/imgs'\n\ngm(dir + \"/original.jpg\")\n .crop(140,100)\n .background(\"#FF0000"
},
{
"path": "examples/bitdepth.js",
"chars": 339,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/blur.js",
"chars": 337,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/changeFormat.js",
"chars": 328,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/charcoal.js",
"chars": 340,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/chop.js",
"chars": 347,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/colorize.js",
"chars": 348,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/colors.js",
"chars": 337,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/comment.js",
"chars": 350,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/compare.js",
"chars": 544,
"preview": "var gm = require('../')\n , dir = __dirname + '/imgs'\n , imgs = 'bitdepth.png original.jpg'.split(' ').map(function (im"
},
{
"path": "examples/contrast.js",
"chars": 339,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/crop.js",
"chars": 350,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/cycle.js",
"chars": 333,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/despeckle.js",
"chars": 340,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/dither.js",
"chars": 350,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/drawing.js",
"chars": 946,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/edge.js",
"chars": 331,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/emboss.js",
"chars": 335,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/enhance.js",
"chars": 336,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/equalize.js",
"chars": 338,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/extent.js",
"chars": 362,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/flatten.js",
"chars": 336,
"preview": "// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __d"
},
{
"path": "examples/flip.js",
"chars": 330,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/flop.js",
"chars": 330,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/gamma.js",
"chars": 345,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/getters.js",
"chars": 412,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/gravity.js",
"chars": 423,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/implode.js",
"chars": 339,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/label.js",
"chars": 346,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/limit.js",
"chars": 373,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/lower.js",
"chars": 338,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/magnify.js",
"chars": 340,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/median.js",
"chars": 335,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/minify.js",
"chars": 335,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/modulate.js",
"chars": 351,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/monochrome.js",
"chars": 342,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/morph.js",
"chars": 343,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/negative.js",
"chars": 338,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/new.js",
"chars": 453,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/noise1.js",
"chars": 336,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/noise2.js",
"chars": 344,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/paint.js",
"chars": 333,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/quality.js",
"chars": 341,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/raise.js",
"chars": 338,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/region.js",
"chars": 418,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/resample.js",
"chars": 350,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/resize.js",
"chars": 346,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/roll.js",
"chars": 357,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/rotate.js",
"chars": 348,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/scale.js",
"chars": 343,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/sepia.js",
"chars": 336,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/sharpen.js",
"chars": 343,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/size.js",
"chars": 347,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/solarize.js",
"chars": 342,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/source_buffer.js",
"chars": 328,
"preview": "var gm = require('../')\n , fs = require('fs')\n , dir = __dirname + '/../examples/imgs'\n\nvar buf = fs.readFileSync(di"
},
{
"path": "examples/spread.js",
"chars": 336,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/swirl.js",
"chars": 345,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/thumb.js",
"chars": 331,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/thumbExact.js",
"chars": 336,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n , dir = __"
},
{
"path": "examples/thumbnail.js",
"chars": 268,
"preview": "var gm = require('../')\n , dir = __dirname + '/imgs'\n \ngm(dir + '/original.jpg')\n .thumbnail(150, 150)\n .write(dir +"
},
{
"path": "index.js",
"chars": 3185,
"preview": "\n/**\n * Module dependencies.\n */\n\nvar Stream = require('stream').Stream;\nvar EventEmitter = require('events').EventEmitt"
},
{
"path": "lib/args.js",
"chars": 36136,
"preview": "/**\n * Dependencies\n */\n\nvar argsToArray = require('./utils').argsToArray;\nvar isUtil = require('./utils').isUtil;\n/**\n "
},
{
"path": "lib/command.js",
"chars": 11229,
"preview": "\n/**\n * Module dependencies.\n */\n\nvar spawn = require('cross-spawn');\nvar utils = require('./utils');\nvar debug = requir"
},
{
"path": "lib/compare.js",
"chars": 4151,
"preview": "// compare\n\nvar spawn = require('cross-spawn');\nvar debug = require('debug')('gm');\nvar utils = require('./utils');\n\n/**"
},
{
"path": "lib/composite.js",
"chars": 778,
"preview": "// composite\n\n/**\n * Composite images together using the `composite` command in graphicsmagick.\n *\n * gm('/path/to/image"
},
{
"path": "lib/convenience/autoOrient.js",
"chars": 1447,
"preview": "\n/**\n * Extend proto.\n */\n\nmodule.exports = function (proto) {\n\n var exifTransforms = {\n topleft: ''\n , top"
},
{
"path": "lib/convenience/morph.js",
"chars": 1389,
"preview": "\n/**\n * Module dependencies.\n */\n\nvar fs = require('fs');\nvar parallel = require('array-parallel');\n\n/**\n * Extend proto"
},
{
"path": "lib/convenience/sepia.js",
"chars": 164,
"preview": "\n/**\n * Extend proto.\n */\n\nmodule.exports = function (proto) {\n proto.sepia = function sepia () {\n return this.modul"
},
{
"path": "lib/convenience/thumb.js",
"chars": 1987,
"preview": "\n/**\n * Extend proto.\n */\n\nmodule.exports = function (proto) {\n\n proto.thumb = function thumb (w, h, name, quality, ali"
},
{
"path": "lib/convenience.js",
"chars": 233,
"preview": "\n/**\n * Extend proto\n */\n\nmodule.exports = function (proto) {\n require(\"./convenience/thumb\")(proto);\n require(\"./conv"
},
{
"path": "lib/drawing.js",
"chars": 4255,
"preview": "\n/**\n * Module dependencies.\n */\n\nvar escape = require('./utils').escape;\n\n/**\n * Extend proto.\n */\n\nmodule.exports = fu"
},
{
"path": "lib/getters.js",
"chars": 8044,
"preview": "/**\n * Extend proto.\n */\n\nmodule.exports = function (gm) {\n\n var proto = gm.prototype;\n\n /**\n * `identify` states\n "
},
{
"path": "lib/montage.js",
"chars": 560,
"preview": "// montage\n\n/**\n * Montage images next to each other using the `montage` command in graphicsmagick.\n *\n * gm('/path/to/i"
},
{
"path": "lib/options.js",
"chars": 304,
"preview": "\nmodule.exports = exports = function (proto) {\n proto._options = {};\n\n proto.options = function setOptions (options) {"
},
{
"path": "lib/utils.js",
"chars": 776,
"preview": "\n/**\n * Escape the given shell `arg`.\n *\n * @param {String} arg\n * @return {String}\n * @api public\n */\n\nexports.escape ="
},
{
"path": "package.json",
"chars": 1067,
"preview": "{\n \"name\": \"gm\",\n \"description\": \"GraphicsMagick and ImageMagick for node.js\",\n \"version\": \"1.25.1\",\n \"author\": \"Aar"
},
{
"path": "test/109.js",
"chars": 374,
"preview": "const fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n "
},
{
"path": "test/118.js",
"chars": 692,
"preview": "/*\n * If only the width is specified for a resize operation,\n * GraphicsMagick requires the format\n * -resize 10x\n * whi"
},
{
"path": "test/393.js",
"chars": 578,
"preview": "const assert = require('assert');\nconst fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (_,"
},
{
"path": "test/417.js",
"chars": 930,
"preview": "\nconst assert = require('assert')\nconst fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (_,"
},
{
"path": "test/422.js",
"chars": 1818,
"preview": "const fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n"
},
{
"path": "test/429.js",
"chars": 933,
"preview": "const fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n"
},
{
"path": "test/68.js",
"chars": 1400,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\nvar assert = require('assert')\nvar ur"
},
{
"path": "test/70.js",
"chars": 1033,
"preview": "\nconst assert = require('assert')\nconst path = require('path');\n\nvar times = 16;\nvar loading = path.join(__dirname, 'fix"
},
{
"path": "test/78.js",
"chars": 568,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/alpha.js",
"chars": 1094,
"preview": "const assert = require('assert');\nconst Async = require('async');\nconst path = require('path');\n\nmodule.exports = functi"
},
{
"path": "test/append.js",
"chars": 1969,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagi"
},
{
"path": "test/arc.js",
"chars": 792,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/autoOrient.js",
"chars": 988,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/autoOrientAll.js",
"chars": 3534,
"preview": "const assert = require('assert');\nconst fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (_,"
},
{
"path": "test/autoOrientAndThumb.js",
"chars": 1007,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagi"
},
{
"path": "test/autoOrientStream.js",
"chars": 1346,
"preview": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n// This is a copy of `autoOrient.js` "
},
{
"path": "test/background.js",
"chars": 652,
"preview": "const assert =require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var "
},
{
"path": "test/bezier.js",
"chars": 807,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/bitdepth.js",
"chars": 434,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/blur.js",
"chars": 433,
"preview": "\nconst assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n v"
},
{
"path": "test/changeFormat.js",
"chars": 256,
"preview": "const path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n if (!GM.integration)\n return finis"
},
{
"path": "test/charcoal.js",
"chars": 437,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/chop.js",
"chars": 444,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/circle.js",
"chars": 796,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n var"
},
{
"path": "test/colorize.js",
"chars": 452,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/colors.js",
"chars": 431,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/comment.js",
"chars": 459,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/compare.js",
"chars": 1686,
"preview": "const path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (gm, dir, finish) {\n // Same image\n "
},
{
"path": "test/composite.js",
"chars": 620,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n cons"
},
{
"path": "test/contrast.js",
"chars": 445,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n cons"
},
{
"path": "test/crop.js",
"chars": 668,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMag"
},
{
"path": "test/cycle.js",
"chars": 426,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n cons"
},
{
"path": "test/densityGm.js",
"chars": 798,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMag"
},
{
"path": "test/despeckle.js",
"chars": 409,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n var "
},
{
"path": "test/dispose.js",
"chars": 1321,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (img, dir, finish, gm, imageMa"
},
{
"path": "test/dither.js",
"chars": 503,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n if ("
},
{
"path": "test/edge.js",
"chars": 394,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/ellipse.js",
"chars": 717,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/emboss.js",
"chars": 430,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/enhance.js",
"chars": 405,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/equalize.js",
"chars": 409,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/extent.js",
"chars": 533,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/flatten.js",
"chars": 648,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/flip.js",
"chars": 394,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/flop.js",
"chars": 394,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/fromBuffer.js",
"chars": 1131,
"preview": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = function (_, "
},
{
"path": "test/gamma.js",
"chars": 451,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/geometry.js",
"chars": 488,
"preview": "\nvar assert = require('assert')\n\nmodule.exports = function (_, __, finish, GM, imageMagick) {\n var a = GM(\"dummy\").opti"
},
{
"path": "test/getterColor.js",
"chars": 413,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/getterDepth.js",
"chars": 431,
"preview": "\nvar assert = require('assert')\n\nmodule.exports = function (gm, dir, finish, GM) {\n if (!GM.integration)\n return fin"
},
{
"path": "test/getterFilesize.js",
"chars": 891,
"preview": "\nvar assert = require('assert')\n\nmodule.exports = function (gm, dir, finish, GM) {\n if (!GM.integration)\n return fin"
},
{
"path": "test/getterFormat.js",
"chars": 315,
"preview": "\nvar assert = require('assert');\n\nmodule.exports = function (gm, dir, finish, GM) {\n if (!GM.integration)\n return fi"
},
{
"path": "test/getterFormatGIF.js",
"chars": 424,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/getterIdentify.js",
"chars": 3736,
"preview": "const assert = require('assert');\nconst path = require('path');\nconst os = require('os')\n\nvar isLinux = os.platform() =="
},
{
"path": "test/getterIptc.js",
"chars": 586,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/getterMultipleIptc.js",
"chars": 723,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/getterRes.js",
"chars": 405,
"preview": "\nvar assert = require('assert')\n\nmodule.exports = function (gm, dir, finish, GM) {\n if (!GM.integration)\n return fin"
},
{
"path": "test/getterSize.js",
"chars": 1357,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/gh-17.js",
"chars": 551,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n var"
},
{
"path": "test/gifFrame.js",
"chars": 372,
"preview": "const path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n if (!gm.integration)\n "
},
{
"path": "test/gifFrameIdentify.js",
"chars": 440,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagi"
},
{
"path": "test/gifFrameStream.js",
"chars": 605,
"preview": "const assert = require('assert')\nconst path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (_, "
},
{
"path": "test/gravity.js",
"chars": 662,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (img, dir, finish, gm) {\n var"
},
{
"path": "test/implode.js",
"chars": 408,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/index.js",
"chars": 2561,
"preview": "const cp = require('child_process');\nconst path = require('path');\nconst Async = require('async');\nconst dir = path.join"
},
{
"path": "test/inputIs.js",
"chars": 1241,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm) {\n var e"
},
{
"path": "test/interlace.js",
"chars": 413,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/label.js",
"chars": 450,
"preview": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n var"
},
{
"path": "test/limit.js",
"chars": 604,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/line.js",
"chars": 658,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/lower.js",
"chars": 437,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/magnify.js",
"chars": 491,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n if"
},
{
"path": "test/median.js",
"chars": 430,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/minify.js",
"chars": 450,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n if "
},
{
"path": "test/minifyIM.js",
"chars": 476,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n var"
},
{
"path": "test/modulate.js",
"chars": 461,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/monochrome.js",
"chars": 418,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/montage.js",
"chars": 642,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n con"
},
{
"path": "test/morph-more.js",
"chars": 449,
"preview": "const path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n if (gm._options.imageMagick) return "
},
{
"path": "test/morph.js",
"chars": 368,
"preview": "const path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n if (gm._options.imageMagick) return "
},
{
"path": "test/negative.js",
"chars": 533,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/new.js",
"chars": 821,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/newImage.js",
"chars": 821,
"preview": "// https://github.com/aheckmann/gm/issues/127\n\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = "
},
{
"path": "test/noise1.js",
"chars": 433,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/noise2.js",
"chars": 451,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/options.js",
"chars": 2095,
"preview": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs');\n\nconst checkCmd = (cmd, imageM"
},
{
"path": "test/paint.js",
"chars": 427,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/polygon.js",
"chars": 731,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/polyline.js",
"chars": 735,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/quality.js",
"chars": 435,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/raise.js",
"chars": 437,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/rectangle.js",
"chars": 760,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/region.js",
"chars": 461,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/repagePlus.js",
"chars": 403,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/resample.js",
"chars": 454,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/resize.js",
"chars": 1466,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMa"
},
{
"path": "test/resizeAndAutoOrientFromBuffer.js",
"chars": 1287,
"preview": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = function (_, "
},
{
"path": "test/resizeBuffer.js",
"chars": 1291,
"preview": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = function (_, "
},
{
"path": "test/resizeWrong.js",
"chars": 1018,
"preview": "const path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n if (!gm.integration)\n "
},
{
"path": "test/roll.js",
"chars": 437,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/rotate.js",
"chars": 760,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/scale.js",
"chars": 1144,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMa"
},
{
"path": "test/selectFrame.js",
"chars": 543,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/sepia.js",
"chars": 513,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/setFormat.js",
"chars": 361,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/sharpen.js",
"chars": 446,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/solarize.js",
"chars": 448,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/spread.js",
"chars": 433,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/streamIn.js",
"chars": 575,
"preview": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (_,"
},
{
"path": "test/streamInGetter.js",
"chars": 487,
"preview": "const path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n "
},
{
"path": "test/streamInOut.js",
"chars": 565,
"preview": "const path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n\n"
},
{
"path": "test/streamOut.js",
"chars": 795,
"preview": "const path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n if (!GM.in"
},
{
"path": "test/streamOutFormat.js",
"chars": 1231,
"preview": "const assert = require('assert')\nconst path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (gm,"
},
{
"path": "test/strip.js",
"chars": 448,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n if"
},
{
"path": "test/subclass.js",
"chars": 1043,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMag"
},
{
"path": "test/swirl.js",
"chars": 431,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/text.js",
"chars": 699,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n va"
},
{
"path": "test/thumb.js",
"chars": 287,
"preview": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n if"
}
]
// ... and 6 more files (download for full content)
About this extraction
This page contains the full source code of the aheckmann/gm GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 206 files (229.9 KB), approximately 69.0k tokens, and a symbol index with 42 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.