1.0.1 • Public • Published

    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.


    Node.js 0.8-0.10.



    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

    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

    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
      .pipe(gd.crop({width: 100, height: 100}))
    // Watermarking
    // Changing image format
    // Combine everything
        gd.resize({width: 800, height: 600})
          .watermark('logo.png', {x:1, y:1})
          .options({format: 'jpeg', quality: '90'})

    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
      .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.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')
      .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)
      // ...
    // Every error raised or returned by easy-gd is a descendant or gd.Error
    try {
    } 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.


    npm i easy-gd

    DownloadsWeekly Downloads






    Last publish


    • furagu