Lwip
Light Weight Image Processor for NodeJS
Install / Use
/learn @EyalAr/LwipREADME
Light-weight image processor for NodeJS
- Overview
- Installation
- Usage
- Supported formats
- Colors specification
- Note on transparent images
- Note on threading performance
- API
- Open an image from file or buffer
- Create a new blank image
- Image operations 0. Resize 0. Scale 0. Contain 0. Cover 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 0. Fade (adjust transparency) 0. Opacify 0. Paste 0. Set pixel 0. Set metadata
- Getters 0. Width 0. Height 0. Pixel 0. Clone 0. Extract / Copy 0. Get as a Buffer 0. JPEG 0. PNG 0. GIF 0. Write to file 0. Get metadata
- Batch operations
- 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.
Note: Installation of this module involves compiling native code.
If npm install lwip failes, you probably need to setup your system.
See instructions.
Building on Windows with Visual Studio requires version 2013 or higher.
Usage
Typical workflow:
- Open an image and get an image object.
- Manipulate it.
- 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, 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, transparency supported.
- GIF, transparency supported. Animated GIFs can be read, but only the first frame will be retrieved.
Encoding (writing):
- JPEG, 3 channels (RGB).
- PNG (lossless), 3 channels (RGB) or 4 channels (RGBA).
- GIF (no animations)
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.
Colors specification
In LWIP colors are coded as RGBA values (red, green, blue and an alpha channel).
Colors are specified in one of three ways:
-
As a string. possible values:
"black" // {r: 0, g: 0, b: 0, a: 100} "white" // {r: 255, g: 255, b: 255, a: 100} "gray" // {r: 128, g: 128, b: 128, a: 100} "red" // {r: 255, g: 0, b: 0, a: 100} "green" // {r: 0, g: 255, b: 0, a: 100} "blue" // {r: 0, g: 0, b: 255, a: 100} "yellow" // {r: 255, g: 255, b: 0, a: 100} "cyan" // {r: 0, g: 255, b: 255, a: 100} "magenta" // {r: 255, g: 0, b: 255, a: 100} -
As an array
[R, G, B, A]whereR,GandBare integers between 0 and 255 andAis an integer between 0 and 100. -
As an object
{r: R, g: G, b: B, a: A}whereR,GandBare integers between 0 and 255 andAis an integer between 0 and 100.
Note: The A value (alpha channel) is always optional and defaults to
100 (completely opaque).
Note on transparent images
- Transparency is supported through an alpha channel which ranges between 0 and 100. 0 is completely transparent and 100 is completely opaque.
- Not all formats support transparency. If an image with an alpha channel is encoded with a format which does not support transparency, the alpha channel will be ignored (effectively setting it to 100% for all pixels).
Note on threading performance
All operations are asynchronous, and processing takes place in a thread pool managed by libuv which is part of NodeJS. This thread pool is separate from the event loop used to process HTTP requests, so use of lwip should not significantly affect the handling of HTTP requests by a web application. The thread pool is however shared with other threaded native modules such as those providing database and filesystem IO.
The default thread pool size of 4 will be appropriate for most applications. However if your application regularly processes many images concurrently and and you wish to take full advantage of a multicore system or prevent heavy image processing work from delaying database or filesystem IO, you may want to increase the size of the thread pool by setting the UV_THREADPOOL_SIZE environmental variable to the NodeJS process, e.g.:
UV_THREADPOOL_SIZE=8 node your_script.js
API
All operations are done on an image object. An image object can be obtained
by:
- Openning an existing image file or buffer with the
openmethod. - Creating a new image object with the
createmethod. - Cloning an existing image object with the
image.clonemethod. - Extracting a sub-image from an existing image object with the
image.extractmethod.
Open an image
lwip.open(source, type, callback)
source {String/Buffer}: The path to the image on disk or an image buffer.type {String/Object}: Optional type of the image. If omitted, the type will be inferred from the file extension. Ifsourceis a buffer,typemust be specified. Ifsourceis an encoded image buffer,typemust be a string of the image type (i.e."jpg"). Ifsourceis a raw pixels buffertypemust be an object withtype.widthandtype.heightproperties.callback {Function(err, image)}
Note about raw pixels buffers: source may be a buffer of raw pixels. The
buffer may contain pixels of 1-4 channels, where:
- 1 channel is a grayscale image.
- 2 channels is a grayscale image with an alpha channel.
- 3 channels is an RGB image.
- 4 channels is an RGBA image (with an alpha channel).
In other words, if the image in the buffer has width W and height H, the
size of the buffer can be W*H, 2*W*H, 3*W*H or 4*W*H.
The channel values in the buffer must be stored sequentially. I.e. first all the Red values, then all the Green values, etc.
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.
});
});
Create a new image
lwip.create(width, height, color, callback)
width {Integer>0}: The width of the new image.height {Integer>0}: The height of the new image.color {String / Array / Object}: Optional Color of the canvas. See colors specification. Defaults to a transparent canvas{r:0, g:0, b:0, a:0}.callback {Function(err, image)}
Example:
var lwip = require('lwip');
lwip.create(500, 500, 'yellow', function(err, image){
// check err
// 'image' is a 500X500 solid yellow c
