Skip to content

EyalAr/lwip

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Sep 17, 2014
6cc0162 · Sep 17, 2014

History

98 Commits
Sep 15, 2014
Sep 14, 2014
Sep 15, 2014
Sep 17, 2014
Jul 20, 2014
Sep 12, 2014
Sep 3, 2014
Jul 1, 2014
Sep 15, 2014
Sep 14, 2014
Sep 15, 2014
Sep 17, 2014
Sep 17, 2014

Repository files navigation

Version Build Status Stories in Ready Stories in Ready

Light-weight image processor for NodeJS

  1. Overview
  2. Installation
  3. Usage
  4. Supported formats
  5. API
  6. Open an image from file or buffer
  7. Image operations 0. Resize 0. Scale 0. Rotate 0. Crop 0. Blur 0. Sharpen 0. Mirror 0. Flip 0. Border 0. Pad 0. Adjust saturation 0. Adjust lightness: lighten / darken 0. Adjust hue
  8. Getters 0. Width 0. Height 0. Get as a Buffer 0. JPEG 0. PNG 0. Write to file
  9. Batch operations
  10. Copyrights

Overview

This module provides comprehensive, fast, and simple image processing and manipulation capabilities.

There are no external runtime dependencies, which means you don't have to install anything else on your system.

This module is in active development. New features are being added.

Read the background for the development of this module.

Installation

npm install lwip

Or, clone this repo and cd lwip && npm install.

You can run tests with npm test.

Usage

Typical workflow:

  1. Open an image and get an image object.
  2. Manipulate it.
  3. Save to disk / Send image buffer over network / etc.

Example (batch operations):

// obtain an image object:
require('lwip').open('image.jpg', function(err, image){
  
  // check err...
  // define a batch of manipulations and save to disk as JPEG:
  image.batch()
    .scale(0.75)          // scale to 75%
    .rotate(45, 'white')  // rotate 45degs clockwise (white fill)
    .crop(200)            // crop a 200X200 square from center
    .blur(5)              // Gaussian blur with SD=5
    .writeFile('output.jpg', function(err){
      // check err...
      // done.
    });

});

Example (non-batch):

var lwip = require('lwip');

// obtain an image object:
lwip.open('image.jpg', function(err, image){
  
  // check err...
  // manipulate image:
  image.scale(0.5, function(err, image){

    // check err...
    // manipulate some more:
    image.rotate(45, 'white', function(err, image){

      // check err...
      // encode to jpeg and get a buffer object:
      image.toBuffer('jpg', function(err, buffer){

        // check err...
        // save buffer to disk / send over network / etc.

      });

    });

  });

});

Supported formats

Decoding (reading):

  • JPEG, 1 & 3 channels (grayscale & RGB).
  • PNG, 1 & 3 channels (grayscale & RGB). Alpha channel (transperancy) is not currently supported.

Encoding (writing):

  • JPEG, 3 channels (RGB).
  • PNG (lossless), 3 channels (RGB).

Other formats may also be supported in the future, but are probably less urgent. Check the issues to see which formats are planned to be supported. Open an issue if you need support for a format which is not already listed.

API

All operations are done on an image object. An image object is obtained with the open method.

Open an image

open(source, type, callback)

  1. source {String/Buffer}: The path to the image on disk or an image buffer.
  2. type {String}: Optional type of the image. If omitted, the type will be inferred from the file extension. If source is a buffer, type must be specified.
  3. callback {Function(err, image)}

Open file example

var lwip = require('lwip');
lwip.open('path/to/image.jpg', function(err, image){
    // check 'err'. use 'image'.
    // image.resize(...), etc.
});

Open buffer example

var fs = require('fs'),
    lwip = require('lwip');

fs.readFile('path/to/image.png', function(err, buffer){
  // check err
  lwip.open(buffer, 'png', function(err, image){
      // check 'err'. use 'image'.
      // image.resize(...), etc.
  });
});

Image operations

Resize

image.resize(width, height, inter, callback)

  1. width {Integer}: Width in pixels.
  2. height {Integer}: Optional height in pixels. If omitted, width will be used.
  3. inter {String}: Optional interpolation method. Defaults to "lanczos". Possible values:
    • "nearest-neighbor"
    • "moving-average"
    • "linear"
    • "grid"
    • "cubic"
    • "lanczos"
  4. callback {Function(err, image)}

Scale

image.scale(wRatio, hRatio, inter, callback)

  1. wRatio {Float}: Width scale ratio.
  2. hRatio {Float}: Optional height scale ratio. If omitted, wRatio will be used.
  3. inter {String}: Optional interpolation method. Defaults to "lanczos". Possible values:
    • "nearest-neighbor"
    • "moving-average"
    • "linear"
    • "grid"
    • "cubic"
    • "lanczos"
  4. callback {Function(err, image)}

Rotate

image.rotate(degs, color, callback)

  1. degs {Float}: Clockwise rotation degrees.
  2. color {String / Array / Object}: Optional Color of the canvas.
  • As a string, possible values: "black", "white", "gray", "blue", "red", "green", "yellow", "cyan", "magenta".
  • As an array [R, G, B] where R, G and B are integers between 0 and 255.
  • As an object {r: R, g: G, b: B} where R, G and B are integers between 0 and 255.
  1. callback {Function(err, image)}

Crop

Crop with rectangle coordinates

image.crop(left, top, right, bottom, callback)

  1. left, top, right, bottom {Integer}: Coordinates of the crop rectangle.
  2. callback {Function(err, image)}

Crop a rectangle from center

image.crop(width, height, callback)

  1. width, height {Integer}: Width and height of the rectangle to crop from the center of the image.
  2. callback {Function(err, image)}

Blur

Gaussian blur.

image.blur(sigma, callback)

  1. sigma {Float>=0}: Standard deviation of the Gaussian filter.
  2. callback {Function(err, image)}

Sharpen

Inverse diffusion shapren.

image.sharpen(amplitude, callback)

  1. amplitude {Float}: Sharpening amplitude.
  2. callback {Function(err, image)}

Mirror

Mirror an image along the 'x' axis, 'y' axis or both.

image.mirror(axes, callback)

  1. axes {String}: 'x', 'y' or 'xy'.
  2. callback {Function(err, image)}

Flip

Alias of mirror.

Border

Add a colored border to the image.

image.border(width, color, callback)

  1. width {Integer}: Border width in pixels.
  2. color {String / Array / Object}: Optional Color of the border.
  • As a string, possible values: "black", "white", "gray", "blue", "red", "green", "yellow", "cyan", "magenta".
  • As an array [R, G, B] where R, G and B are integers between 0 and 255.
  • As an object {r: R, g: G, b: B} where R, G and B are integers between 0 and 255.
  1. callback {Function(err, image)}

Pad

Pad image edges with colored pixels.

image.pad(left, top, right, bottom, color, callback)

  1. left, top, right, bottom {Integer}: Number of pixels to add to each edge.
  2. color {String / Array / Object}: Optional Color of the padding.
  • As a string, possible values: "black", "white", "gray", "blue", "red", "green", "yellow", "cyan", "magenta".
  • As an array [R, G, B] where R, G and B are integers between 0 and 255.
  • As an object {r: R, g: G, b: B} where R, G and B are integers between 0 and 255.
  1. callback {Function(err, image)}

Saturate

Adjust image saturation.

image.saturate(delta, callback)

  1. delta {Float}: By how much to increase / decrease the saturation.
  2. callback {Function(err, image)}

Examples:

  1. image.saturate(0, ...) will have no effect on the image.
  2. image.saturate(0.5, ...) will increase the saturation by 50%.
  3. image.saturate(-1, ...) will decrease the saturation by 100%, effectively desaturating the image.

Lighten

Adjust image lightness.

image.lighten(delta, callback)

  1. delta {Float}: By how much to increase / decrease the lightness.
  2. callback {Function(err, image)}

Examples:

  1. image.lighten(0, ...) will have no effect on the image.
  2. image.lighten(0.5, ...) will increase the lightness by 50%.
  3. image.lighten(-1, ...) will decrease the lightness by 100%, effectively making the image black.

Darken

Adjust image lightness.

image.darken(delta, callback)

Equivalent to image.lighten(-delta, callback).

Hue

Adjust image hue.

image.hue(shift, callback)

  1. shift {Float}: By how many degrees to shift each pixel's hue.
  2. callback {Function(err, image)}

Examples:

  1. image.lighten(0, ...) will have no effect on the image.
  2. image.lighten(100, ...) will shift pixels' hue by 100 degrees.

Note: The hue is shifted in a circular manner in the range [0,360] for each pixel individually.

Getters

Width

image.width() returns the image's width in pixels.

Height

image.height() returns the image's height in pixels.

Get as a Buffer

Get encoded binary image data as a NodeJS Buffer.

When opening an image, it is decoded and stored in memory as an uncompressed image. All manipulations are done on the uncompressed data in memory. This method allows to encode the image to one of the specified formats and get the encoded data as a NodeJS Buffer object.

image.toBuffer(format, params, callback)

  1. format {String}: Encoding format. Possible values:
  • "jpg"
  • "png"
  1. params {Object}: Optional Format-specific parameters (See below).
  2. callback {Function(err, buffer)}

Supported encoding formats:

JPEG

The params object should have the following fields:

  • quality {Integer}: Defaults to 100.
PNG

The params object should have the following fields:

  • compression {String}: Defaults to "fast". Possible values:
    • "none" - No compression. Fastest.
    • "fast" - Basic compression. Fast.
    • "high" - High compression. Slowest.
  • interlaced {Boolean}: Defaults to false.

Write to file

Write encoded binary image data directly to a file.

image.writeFile(path, format, params, callback)

  1. path {String}: Path of file to write.
  2. format {String}: Optional Encoding format. If omitted, will be inferred from path extension. Possible values are specified in Get as a Buffer section.
  3. params {Object}: Optional Format-specific parameters.
  4. callback {Function(err)}

Batch operations

Each of the image operations above can be done as part of a batch of operations. Operations can be queued, and executed as a batch at any time.

Each one of the image operations has a batch equivalent which takes the same arguments, except the callback, which is not needed.

When all batch operations had been queued, they can be executed in one of several methods, as explained below.

Obtaining a batch object

In order to start queueing operations, a batch object first needs to be obtained from the image.

// obtain a batch object from the image:
var batch = image.batch();

Using a batch object

Use the batch object to queue image operations. Each of the operations above has a batch equivalent. Operations can be chained.

Remember, the batch manipulation methods do not take a callback.

Example:

batch.rotate(45, 'white').scale(0.5).blur(5);

Executing a batch

There are several methods which start the execution of a batch. Once a batch finishes an execution, it becomes empty and can be resued to queue additional operations.

Execute batch and obtain the manipulated image object

When all desired operations had been queued, execute the batch with the exec() method. exec takes a callback argument; callback is a function which receives an error object and the manipulated image object:

batch.exec(callback)

  • callback {Function(err, image)}:
    • err: An error object or null when no error.
    • image: An image object of the manipulated image.
batch.exec(function(err, image){
  // check err, use image
});
Execute batch and obtain a Buffer object

Batch objects have a toBuffer convenience method.

batch.toBuffer(format, params, callback)

See parameters of image.toBuffer().

Execute batch and write to file

Batch objects have a writeFile convenience method.

batch.writeFile(path, format, params, callback)

See parameters of image.writeFile().

Notes on batch operations

An image can have more than one batch object, but all batch objects modify the same underlying image. This means the order of execution matters.

var batch1 = image.batch().rotate('45', 'black');
var batch2 = image.batch().border(15, 'black');

This will rotate the image 45degs and then add a black border:

batch1.exec(function(err, image){
    batch2.exec(function(err, image){
        // ...
    });
});

While this will add a black border and then rotate the image 45degs:

batch2.exec(function(err, image){
    batch1.exec(function(err, image){
        // ...
    });
});

Copyrights

The native part of this module is compiled from source which uses the following: