Image Processing in Node.js Using Jimp Library – Coding Shiksha

Image Processing in Node.js Using Jimp Library – Coding Shiksha

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

 

  1. 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

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

 

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.

 

  1. 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 modulebuild 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:

READ  Build a Stock HD Photo Finder App in Javascript

 

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.

 

READ  Node.js API Authentication With JWT

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.coverimage.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:

 

image.hash(2); // 1010101011010000101010000100101010010000011001001001010011100100

 

Leave a Reply

Close Menu