A simplified Node.js wrapper around GD image manipulation library with extra features making your life easier.
JavaScript Makefile
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
benchmark
lib
test
.gitignore
.npmignore
.travis.yml
CHANGELOG
LICENSE
Makefile
README.md
index.js
package.json

README.md

easy-gd Build Status

A simplified Node.js wrapper around GD image manipulation library with extra features:

Why should one use easy-gd?

Because it is fast. Easy-gd uses C++ buindings for libgd that add very little overhead. For example, it resizes images two times faster than gm, which executes graphicsmagick commands in the background.

Compatibility

Node.js 0.8-0.10.

Installation

Ubuntu:

sudo apt-get install libgd2-xpm-dev
npm install easy-gd

Mac OS X:

brew install gd
npm install easy-gd

Usage recipes

Resizing images

var gd = require('easy-gd')

var image, resized

image = gd.open('image-800x600.jpg') // Source image size is 800×600

// Resize to feat into 100×100 box, yields 100×75 image
resized = image.resize({width: 100, height: 100})

// Resize by width, yields 200×150 image
resized = image.resize({width: 200})

// Resize by height, yields 267×200 image
resized = image.resize({height: 200})

// Resize and crop to 100×100
resized = image.crop({width: 100, height: 100})
resized = image.resize({width: 100, height: 100, method: 'crop'})

// Resize without resampling; faster but lowers the quality
resized = image.resize({width: 100, height: 100, resample: false})

// Save the resized image
resized.save('resized.jpg')

See also: Reading/writing files, Asynchronous processing, Image transform streams.

Placing a watermark

var gd = require('easy-gd')

var image, watermarked

image = gd.open('source-image.jpg')

// Place a logo at the center of the image
watermarked = image.watermark('logo.png')
watermarked = image.watermark('logo.png', {x: 0.5, y: 0.5})

// At the left top corner
watermarked = image.watermark('logo.png', {x: 0, y: 0})

// At the right bottom corner
watermarked = image.watermark('logo.png', {x: 1, y: 1})

// Choose the most contrast position for a logo at the bottom
watermarked = image.watermark('logo.png', [{x: 0, y: 1}, {x: 0.5, y: 1}, {x: 1, y: 1}])

// Using gd.Image object as a watermark
var logo = gd.open('logo.png')
watermarked = image.watermark(logo)

// Save the watermarked image
watermarked.save('watermarked.jpg')

See also: Reading/writing files, Reading/writing buffers, Reading/writing streams, Asynchronous processing, Error handling.

Reading/writing image files

var gd = require('easy-gd')

var image = gd.open('image.png')

// Do something to the image

image.save('processed.jpg', {quality: 90})

See also: Reading/writing buffers, Reading/writing streams, Asynchronous processing, Controlling the output format, Error handling.

Reading/writing buffers

var gd = require('easy-gd')

// Reading image from buffer
var image = gd.open(imageData)

// Saving image to a buffer
var imageData = image.save()

// Using buffer as a watermark source
var watermarked = image.watermark(imageData)

See also: Reading/writing files, Reading/writing streams, Asynchronous processing, Controlling the output format, Error handling.

Reading/writing streams

var gd = require('easy-gd')

// Reading image from stream
gd.open(stream, function (error, image) {
  if (!error) {
    // Process the image
  }
})

// Saving image to a stream
image.save(stream, function (error) {
  if (!error) {
    // Some action
  }
})

// Using stream as a watermark source
image.watermark(stream, function (error, watermarked) {
  if (!error) {
    // Process the watermarked image
  }
})

See also: Image transform streams, Reading/writing files, Reading/writing buffers, Controlling the output format, Error handling.

Image transform streams

All the image manipulation methods called directly on the module object produce chainable transform streams:

var gd = require('easy-gd')

// Making thumbnails
process.stdin
  .pipe(gd.crop({width: 100, height: 100}))
  .pipe(process.stdout)

// Watermarking
process.stdin
  .pipe(gd.watermark('logo.png'))
  .pipe(process.stdout)

// Changing image format
process.stdin
  .pipe(gd.format('jpeg').quality(90))
  .pipe(process.stdout)

// Combine everything
process.stdin
  .pipe(
    gd.resize({width: 800, height: 600})
      .watermark('logo.png', {x:1, y:1})
      .options({format: 'jpeg', quality: '90'})
  )
  .pipe(process.stdout)

See also: Reading/writing files, Reading/writing buffers, Reading/writing streams, Controlling the output format, Error handling.

Synchronous image processing

With easy-gd you can synchronously process files and buffers:

var gd = require('easy-gd')

// Processing files
gd.open('input.png')
  .resize({width: 800, height: 600})
  .save('output.jpg', {quality: 90})

// Processing buffers
var outputData = gd.open(inputData)
  .resize({width: 800, height: 600})
  .save({format: 'jpeg', quality: 90})

See also: Asynchronous processing, Error handling.

Asynchronous image processing

You can asynchronously process files, buffers and streams by passing additional callback argument:

var gd = require('easy-gd')

// Processing files
gd.open('input.png', function (error, image) {
  if (error) throw error
  image.resize({width: 800, height: 600}, function (error, resized) {
    if (error) throw error
    resized.save('output.jpg', {quality: 90}, function (error) {
      if (error) throw error
    })
  })
})

// Processing buffers
gd.open(inputData, function (error, image) {
  if (error) throw error
  image.resize({width: 800, height: 600}, function (error, resized) {
    if (error) throw error
    resized.save({format: 'jpeg', quality: 90}, function (error, outputData) {
      if (error) throw error
      // Process outputData buffer
    })
  })
})

// Processing streams
gd.open(inputStream, function (error, image) {
  if (error) throw error
  image.resize({width: 800, height: 600}, function (error, resized) {
    if (error) throw error
    resized.save(outputStream, {format: 'jpeg', quality: 90}, function (error) {
      if (error) throw error
    })
  })
})

See also: Image transform streams, Synchronous processing, Error handling.

Controlling the output format

var gd = require('easy-gd')

// Format is inherited from the source image
var image = gd.open('input.jpg')
var resizedBuffer = image.resize({width: 100}).save() // Saved in JPEG

// Format can be specified explicitly with target filename extension
var image = gd.open('input.jpg')
image.save('output.png') // Saved in PNG

// Format can be specified explicitly with save({format: 'format_name'})
var image = gd.open('input.jpg')
var pngBuffer = image.save({format: 'png'}) // Saved in PNG

// Target file extension has higher priority
var image = gd.open('input.png')
image.save('output.jpg') // Saved in JPEG

Format specification priority: filename extension > save 'format' option > inherited format.

See also: Controlling image quality/compression, Automatic filename extensions, Error handling.

Controlling image quality/compression

var gd = require('easy-gd')
var image = gd.open('input.jpg')

// Setting JPEG file quality, 0-100
image.save('output.jpg', {quality: 90})

// Setting PNG file compression level, 0-9
image.save('ouput.png', {compression: 6})

// Transform stream options
inputStream.pipe(gd.format('png').compression(6)).pipe(outputStream)
inputStream.pipe(gd.format('jpeg').quality(90)).pipe(outputStream)
inputStream.pipe(gd.options({format: 'jpeg', quality: 90}).pipe(outputStream)

// Buffer saving options
var outputBuffer = image.save({format: 'jpeg', quality: 90})
var outputBuffer = image.save({format: 'png', compression: 6})

See also: Controlling the output format, Automatic filename extensions.

Automatic filename extensions

var gd = require('easy-gd')

var image = gd.open('input.jpg')
image.save('output.{ext}', {format: 'png'}) // Writes ouput.png


var image = gd.open('input.jpg')
image
  .resize({width: 100})
  .save('output.{ext}') // Writes output.jpg since format was inherited

See also: Controlling the output format, Controlling image quality/compression.

Reading Exif data

Exif data are being parsed automatically for JPEG images.

var gd = require('easy-gd')

var image = gd.open('input.jpg')

// Accessing Exif tags
if (image.exif) {
  console.log('%s %s', image.exif.GPSLongitude, image.exif.GPSLatitude)
} else {
  console.log('No Exif data')
}

Note: image.exif property will be copied by resize() and other methods, but will not be written to the destination image.

See also: Automatic image orientation.

Automatic image orientation

GD does not process Exif data, resulting rotated images in the output. Easy-gd fixes this by automatically orienting the image.

var gd = require('easy-gd')

// The image gets automatically oriented by Exif data
var image = gd.open('photo.jpg')

// Turn automatic orientation off
var original = gd.open('photo.jpg', {autoOrient: false})

// Automatically orient existing image
var rotated = original.autoOrient()

See also: Reading Exif data.

Error handling

var gd = require('easy-gd')

// Synchronous methods throw exceptions
try {
  var image = gd.open('non-existent.png')
} catch (error) {
  console.log('Failed to open the image: %s', error)
}

// Asynchronous methods return errors as the first callback argument;
// null means there was no error
gd.open('non-existent.png', function (error, image) {
  if (error) {
    console.log('Failed to open the image: %s', error)
    return
  }
  // ...
})

// Every error raised or returned by easy-gd is a descendant or gd.Error
try {
  doImageRelatedStuff()
} catch (error) {
  if (error instanceof gd.Error) {
    console.log('Image processing error: %s', error)
  } else {
    // Some other error happened
  }
}

There are some subclasses you can use to catch specific errors:

  • gd.UnknownSourceType - unknown source type.
  • gd.EmptySource - empty source file or buffer.
  • gd.UnknownImageFormat - unknown image format (or not an image at all).
  • gd.IncompleteImage - corrupted or incomplete image.
  • gd.UnsupportedOrientation - unsupported image Exif orientation tag value.
  • gd.DestinationFormatRequired - destination image format required.
  • gd.UnknownDestinationType - unknown destination type.
  • gd.FileOpen - file opening error.
  • gd.FileDoesNotExist - file does not exist.
  • gd.FileWrite - file writing error.
  • gd.SynchronousStreamAccess - a stream cannot be read or written synchronously.
  • gd.OptionsRequired - options argument should be passed in.