Welcome folks I am back with another blog post. In this blog post we will be talking about a open source library of Node JS ie. JIMP with the help of this library you can do some Complex image processing for example you can resize the image you can change the quality of the image or you can change grayscale of the image so we will be looking in this post various examples of this library so if you visit and pm package manager official website you will see that this package is very famous and it has almost 33000 weekly downloads so you will see that this package is a very popular package among Node JS developers so if you want to do any kind of image processing or if you want to build image processing applications then you can use this open source library it is totally free and the nice thing about this library is that in order to do this you only required this library you don’t require any other dependency because it is a native dependency of JavaScript or Node you can say so apart from this library you don’t need any other library in order to build image processing applications so let’s start by looking at some examples of this library.

Where to Download?

You can visit the Jimp Library Official Package repository at this Link

Installing via NPM

You can install the library JIMP by issuing a simple command in Node something shown below

npm install jimp

What is JIMP?

The question arises in every person mind is that what the hell this JIMP and where it came from. JIMP stands for Javascript Image Manipulation Program. It is a Node module for image manipulation or processing which is written entirely in Javascript Language. No external dependencies is used to make it.

Advantages of JIMP

It is fast and flexible when it comes to processing and manipulation of images as it is entirely written in Javascript.

No 3rd Party Dependency is there when you use JIMP.

It contains native Javascript Code.

It is bug free.

It is a lightweight library.

Supported types:

@jimp/jpeg

@jimp/png

@jimp/bmp

@jimp/tiff

@jimp/gif

Commonly Used Cases

Callback case

var Jimp = require('jimp'); // open a file called "profile.jpg" Jimp.read('profile.jpg', (err, profile) => { if (err) throw err; lenna .resize(256, 256) // resize .quality(60) // set JPEG quality .greyscale() // set greyscale .write('modified.jpg'); // save });

Explanation

First of all we are including the library in the script Secondly we are using the read function in order to open the image file lenna.jpg. The Second argument in the read function specifies the err variable and the actual image file. After that we are checking the result of the method if any kind of error takes place then we simply throwing that error. If any error takes place then we just use the image which is stored in the lenna variable of the callback. Lastly we take the image apply some effects such as resize it, improve quality, apply greyscale and actually saves it to the computer.

Result of Above Code

When we actually execute the above code we get the following result which is shown below. We have the original image you can see but after applying the functions to it we get the another image with greyscale, resize and quality applied to it.

Original Image

Processed Image

The modified image has been resized to 256*256 pixels.

The modified image quality has been reduced to 60.

The modified image has less size. 60 kb reduced to 7kb.

The modified image has been applied greyscale effect.

Using Promises

You can also do the same thing by using promises also. Personally I will prefer this approach over callbacks. Because callbacks can get sometime hard to manage. Also with callbacks the code becomes messier and it becomes hard to code and also for someone to understand your code. So I will prefer you also use promises approach when using this library. The whole source code is shown below on how to use promises with this library.

Jimp.read('lenna.png') .then(lenna => { return lenna .resize(256, 256) // resize .quality(60) // set JPEG quality .greyscale() // set greyscale .write('lena-small-bw.jpg'); // save }) .catch(err => { console.error(err); });

TypeScript Usage

If you are making your application in Typescript. Then it becomes a hell lot easier in importing the library into your project. There are three methods available in Typescript when compared to Javascript. The methods are as follows.

First Method is the import = require() method to import it as a CommonJS Module.

import Jimp = require('jimp');

2. Alternatively you can import it with ES6 default import scheme, if you set the esModuleInterop compiler flag to true in your tsconfig

import Jimp from 'jimp';

3. Lastly you can import it with a synthetic default import. This requires setting the allowSyntheticDefaultImports compiler option to true in your tsconfig



import * as Jimp from 'jimp';

Module Build

If you’re using a web bundles (webpack, rollup, parcel) you can benefit from using the module build of jimp. Using the module build will allow your bundler to understand your code better and exclude things you aren’t using.

import Jimp from 'jimp/es';

WebPack

If you’re using webpack you can set process.browser to true and your build of jimp will exclude certain parts, making it load faster.

{ plugins: [ new webpack.DefinePlugin({ 'process.browser': 'true' }), ... ], }

Jimp Read Method Explanation

The static Jimp.read method takes the path to a file, URL, dimensions, a Jimp instance or a buffer and returns a Promise:

Jimp.read('./path/to/image.jpg') .then(image => { // Do stuff with the image. }) .catch(err => { // Handle an exception. }); Jimp.read('http://www.example.com/path/to/lenna.jpg') .then(image => { // Do stuff with the image. }) .catch(err => { // Handle an exception. }); Jimp.read(jimpInstance) .then(image => { // Do stuff with the image. }) .catch(err => { // Handle an exception. }); Jimp.read(buffer) .then(image => { // Do stuff with the image. }) .catch(err => { // Handle an exception. });

In some cases, you need to pass additional parameters with an image’s URL. You can pass an object to the Jimp.read method:

Jimp.read({ url: 'http://www.example.com/path/to/lenna.jpg', // Required! headers: {}, ... }) .then(image => { // Do stuff with the image. }) .catch(err => { // Handle an exception. });

Methods Supported

There are a bunch of methods supported by this library which are as follows

/* Resize */ image.contain( w, h[, alignBits || mode, mode] ); // scale the image to the given width and height, some parts of the image may be letter boxed image.cover( w, h[, alignBits || mode, mode] ); // scale the image to the given width and height, some parts of the image may be clipped image.resize( w, h[, mode] ); // resize the image. Jimp.AUTO can be passed as one of the values. image.scale( f[, mode] ); // scale the image by the factor f image.scaleToFit( w, h[, mode] ); // scale the image to the largest size that fits inside the given width and height // An optional resize mode can be passed with all resize methods. /* Crop */ image.autocrop([tolerance, frames]); // automatically crop same-color borders from image (if any), frames must be a Boolean image.autocrop(options); // automatically crop same-color borders from image (if any), options may contain tolerance, cropOnlyFrames, cropSymmetric, leaveBorder image.crop( x, y, w, h ); // crop to the given region /* Composing */ image.blit( src, x, y, [srcx, srcy, srcw, srch] ); // blit the image with another Jimp image at x, y, optionally cropped. image.composite( src, x, y, [{ mode, opacitySource, opacityDest }] ); // composites another Jimp image over this image at x, y image.mask( src, x, y ); // masks the image with another Jimp image at x, y using average pixel value image.convolute( kernel ); // applies a convolution kernel matrix to the image or a region /* Flip and rotate */ image.flip( horz, vert ); // flip the image horizontally or vertically image.mirror( horz, vert ); // an alias for flip image.rotate( deg[, mode] ); // rotate the image clockwise by a number of degrees. Optionally, a resize mode can be passed. If `false` is passed as the second parameter, the image width and height will not be resized. /* Colour */ image.brightness( val ); // adjust the brighness by a value -1 to +1 image.contrast( val ); // adjust the contrast by a value -1 to +1 image.dither565(); // ordered dithering of the image and reduce color space to 16-bits (RGB565) image.greyscale(); // remove colour from the image image.invert(); // invert the image colours image.normalize(); // normalize the channels in an image /* Alpha channel */ image.hasAlpha(); // determines if an image contains opaque pixels image.fade( f ); // an alternative to opacity, fades the image by a factor 0 - 1. 0 will haven no effect. 1 will turn the image image.opacity( f ); // multiply the alpha channel by each pixel by the factor f, 0 - 1 image.opaque(); // set the alpha channel on every pixel to fully opaque image.background( hex ); // set the default new pixel colour (e.g. 0xFFFFFFFF or 0x00000000) for by some operations (e.g. image.contain and /* Blurs */ image.gaussian( r ); // Gaussian blur the image by r pixels (VERY slow) image.blur( r ); // fast blur the image by r pixels /* Effects */ image.posterize( n ); // apply a posterization effect with n level image.sepia(); // apply a sepia wash to the image image.pixelate( size[, x, y, w, h ]); // apply a pixelation effect to the image or a region /* 3D */ image.displace( map, offset ); // displaces the image pixels based on the provided displacement map. Useful for making stereoscopic 3D images.

Some of these methods are irreversible, so it can be useful to perform them on a clone of the original image:

image.clone(); // returns a clone of the image

Resize Modes

The default resizing algorithm uses a bilinear method as follows:

image.resize(250, 250); // resize the image to 250 x 250 image.resize(Jimp.AUTO, 250); // resize the height to 250 and scale the width accordingly image.resize(250, Jimp.AUTO); // resize the width to 250 and scale the height accordingly

The other constants that we can use for the resizing algorithm are as follows:

Jimp.RESIZE_NEAREST_NEIGHBOR; Jimp.RESIZE_BILINEAR; Jimp.RESIZE_BICUBIC; Jimp.RESIZE_HERMITE; Jimp.RESIZE_BEZIER;

Align modes

The following constants can be passed to the image.cover , image.contain and image.print methods:

Jimp.HORIZONTAL_ALIGN_LEFT; Jimp.HORIZONTAL_ALIGN_CENTER; Jimp.HORIZONTAL_ALIGN_RIGHT; Jimp.VERTICAL_ALIGN_TOP; Jimp.VERTICAL_ALIGN_MIDDLE; Jimp.VERTICAL_ALIGN_BOTTOM;

Compositing and blend modes

The following modes can be used for compositing two images together. mode defaults to Jimp.BLEND_SOURCE_OVER.

Jimp.BLEND_SOURCE_OVER; Jimp.BLEND_DESTINATION_OVER; Jimp.BLEND_MULTIPLY; Jimp.BLEND_SCREEN; Jimp.BLEND_OVERLAY; Jimp.BLEND_DARKEN; Jimp.BLEND_LIGHTEN; Jimp.BLEND_HARDLIGHT; Jimp.BLEND_DIFFERENCE; Jimp.BLEND_EXCLUSION;

Writing text

Jimp.loadFont(pathOrURL).then(font => { // load font from .fnt file image.print(font, x, y, message); // print a message on an image. message can be a any type image.print(font, x, y, message, maxWidth); // print a message on an image with text wrapped at maxWidth });

Jimp.loadFont(pathOrURL).then(font => { image.print( font, x, y, { text: 'Hello world!', alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER, alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE }, maxWidth, maxHeight ); // prints 'Hello world!' on an image, middle and center-aligned, when x = 0 and y = 0 });

Advanced usage

Colour manipulation

image.color([ { apply: 'hue', params: [-90] }, { apply: 'lighten', params: [50] }, { apply: 'xor', params: ['#06D'] } ]);

Comparing images

To generate a perceptual hash of a Jimp image, based on the pHash algorithm, use:

image.hash(); // aHgG4GgoFjA

By default the hash is returned as base 64. The hash can be returned at another base by passing a number from 2 to 64 to the method: