How to install and use lwip (Light Weight Image Processor) in Windows for Node.js

How to install and use lwip (Light Weight Image Processor) in Windows for Node.js

The image processing is a heavy task to be handled in Javascript, therefore if you want to provide a smooth usage experience in the manipulation and image processing, you will choose lwip among other image processing libraries available for node.js (like jimp, an image processing module written in pure javascript) because lwip uses a native module written in C++, which will make the image processing fast and fluid.

The lwip 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.

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)

In this article you'll learn how to install and use the lwip module in your node.js project easily in a couple of minutes.

1. Install node-gyp globally

You'll need node-gyp in order to use the lwip module. Proceed with the installation of node-gyp as a global variable in the node command prompt executing the following command:

npm install -g node-gyp

node-gyp is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. It bundles the gyp project used by the Chromium team and takes away the pain of dealing with the various differences in build platforms.

2. Installing required tools

To work with lwip we'll need the following tools available on the system:

  • Visual C++ Build Environment.
  • Python v2.7.x , the v3.x versions aren't supported by node-gyp.

Option 1: Automatic installation

Execute the following command in the node command prompt (run as Administrator):

npm install --global --production windows-build-tools

This module will install python 2.7 and the Visual Studio C++ compiler. The installation may take a while, however will make the installation process easy for you.

Windows-build-tools setup and python

Option 2: Manual installation

Go to the downloads area in the official python website and download the latest 2.7.x installer and proceed with the installation as you would do with any installer. Do not forget to add python in your environment variable selecting the option in the setup.

Python 2.7 installer windows setup environment variable

In case you have another python version (i.e v3) you can identify which Python version node-gyp uses by setting the '--python' variable:

node-gyp --python /path/to/python2.7

If node-gyp is called by way of npm and you have multiple versions of Python installed, then you can set npm's 'python' config key to the appropriate value:

npm config set python /path/to/executable/python2.7

Now that you have python, we need only the Visual C++ Build Environment. This can be either installed by the Visual C++ Build environment setup here or the installation of Visual Studio 2015 (or modify an existing installation) and select Common Tools for Visual C++ during setup. This also works with the free Community and Express for Desktop editions.

Once the installation of Visual C++ Build environment is completed, execute the following command in the node command prompt to set the visual studio version to 2015 in the configuration:

npm config set msvs_version 2015

And you're ready to go. If the above steps didn't work for you, please visit Microsoft's Node.js Guidelines for Windows for additional tips.

3. Install lwip in the project

Now that we have all the required tools to compile the native module of lwip, we can start to use it, so proceed finally with the installation of the module executing the following command in the node command prompt:

npm install lwip

The download of the module will start, and it will immediately start the build process (which could take a while). To test if we did everything correctly, we are going to manipulate the following image (image.jpg):

Not now please meme code

And a little script to manipulate it using lwip in node.js (index.js):

var lwip = require('lwip');

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)
    .writeFile('output.jpg', function(err){
        if(err){
            console.log(err);
        }
    });
});

Save the code in a js file (in this case index.js) and test the script using:

node index.js

The previous script should create an image (ouput.jpg) with the following image:

Not now orientation lwip module

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 index.js

4. Use lwip

All operations are done on an image object. An image object can be obtained by:

  1. Openning an existing image file or buffer with the open method.
  2. Creating a new image object with the create method.
  3. Cloning an existing image object with the image.clone method.
  4. Extracting a sub-image from an existing image object with the image.extract method.

Here you'll find a couple of examples of weird tasks that you can achieve with lwip:

Creating an image

The creation of an image comes in handy when you want to take the image as a canvas in which more images are going to be rendered or modified etc. The third parameter provides the color of the canvas, defaults to transparent.

var lwip = require('lwip');

lwip.create(500, 500, 'yellow', function(err, image){
    image.writeFile('myimage.jpg', function(err){
        if(err){
            console.log(err);
        }
    });
});

The previous snippet will create an image (square) of 500x500px with yellow background.

Exporting an image to base64

You can retrieve the base64 content of an image converting the buffer to a string.

var lwip = require('lwip');

lwip.create(300, 300, 'yellow', function(err, image){
    image.toBuffer('png', function(err,buffer) {
        var base64data = buffer.toString('base64');
        var finalBase64String = 'data:image/png;base64,' + base64data;

        console.log(finalBase64String);
    });
});

Note that the buffer will provide the plain base64 data, so if you want to provide a base64 string that can be shown directly in the browser, you need to add the "inlined format".

Manipulating base64 images

You can manipulate images from base64 format directly in lwip without create a static file. Instead, create a new instance of Buffer with the Base64 data on it (remember to remove the unnecesary data, the buffer expects the plain base64 content or the file will be corrupted).

var lwip = require('lwip');

var base64String = "data:image/jpeg;base64,qweqwe.......";

var encondedImageBuffer = new Buffer(base64String.replace(/^data:image\/(png|gif|jpeg);base64,/,''), 'base64');

lwip.open(encondedImageBuffer, 'jpg', function(err, image){
    // check err...
    // define a batch of manipulations and save to disk as JPEG:
    image.batch().writeFile('myimage.jpg', function(err){
        if(err){
            console.log(err);
        }
    });
});

You can read more examples and the documentation of the library in the official repository or the usage area of the readme file.

Have fun !

Become a more social person