npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

easy-gd

v1.0.1

Published

A simplified Node.js wrapper around GD image manipulation library with extra features making your life easier.

Downloads

7

Readme

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.