Node.js: resizing an image without ImageMagick

I am developing a web application for Node.js (+ express 4), where users can set their profile picture by uploading it to the server. We already limit the size of the mimetype file and the maximum file size, so the user cannot upload images larger than 200 KB in png or jpeg.

The problem is that we would like to change (uploaded to the server) the resolution of the uploaded image to 200x200 in order to improve page loading and save disk space. After some research, all answers pointed to the use of any module based on ImageMagick or GraphicsMagick.

However, the need to install ImageMagick / GraphicsMagick to simply resize the image seems to me too redundant, so is there any other solution besides this for Node.js?

Edit: I changed the decision to sharp , as the previous solution (lwip) is no longer supported. Thanks for all your feedback!

+71
image image-resizing
Jun 03 '14 at 10:55
source share
10 answers

I would vote for a sharp

sharp('input.jpg') .resize(200, 200) .toFile('ouput.jpg', function(err) { // output.jpg is a 200 pixels wide and 200 pixels high image // containing a scaled and cropped version of input.jpg }); 

This is fast, usually 6 times faster than the fastest imagemagick-based node bindings , and works in a very small amount of memory, possibly 10 times less . clear links to the libvips image library directly, no external shell , and the library itself is faster and more efficient than * magick in this task. It supports useful features such as input and output of stream, buffer and file system, color management, transparency, promises, overlays, WebP, SVG and much more.

Starting at 0.20, npm will automatically download full compiled binaries on most platforms, so there is no need for node-gyp. Just enter:

 npm install sharp 

or:

 yarn add sharp 

And let's go.

+74
Jan 26 '15 at 10:42
source share

I recently started developing an image processing module for NodeJS without any runtime dependencies ( read why ). It is still in its early stages, but can already be used.

What you ask for will be done as follows:

 image.resize(200, 200, function(err, image){ // encode resized image to jpeg and get a Buffer object image.toBuffer('jpg', function(err, buffer){ // save buffer to disk / send over network / etc. }); }); 

More info in the Github repo module.

+70
Jul 03 '14 at 2:14
source share

Take a look at lwip: https://github.com/EyalAr/lwip

Very simple and easy to use.

 npm install lwip 

and then in your node code,

 // 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. }); }); 

I have successfully implemented this in my file downloader and works like a charm.

+16
Oct 09 '14 at 2:02
source share

There is a good image processing library written entirely in JavaScript, without dependencies with other Jimp libraries. https://github.com/oliver-moran/jimp

Usage example:

 var Jimp = require("jimp"); // open a file called "lenna.png" Jimp.read("lenna.png", function (err, lenna) { if (err) throw err; lenna.resize(256, 256) // resize .quality(60) // set JPEG quality .write("lena-small.jpg"); // save }); 
+10
Dec 12 '15 at 9:43 on
source share

sharp has enjoyed some popularity lately, but its the same idea as * Magick bindings.

However, to install ImageMagick / GraphicsMagick to simply resize the image seems too redundant for me

Resizing an image is nothing but simple. The JPEG format is particularly complex, and there are several ways to scale graphics with results of various quality, some of which are easily implemented. Image processing libraries exist to perform this task, so if you have no other reason why you cannot install them, go to it.

+8
Jun 03 '14 at 10:58
source share

Canvas is 2.3 times faster than ImageMagic.

You can try comparing Node.js modules for image processing - https://github.com/ivanoff/images-manipulation-performance

 author results: sharp.js : 9.501 img/sec; minFreeMem: 929Mb canvas.js : 8.246 img/sec; minFreeMem: 578Mb gm.js : 4.433 img/sec; minFreeMem: 791Mb gm-imagemagic.js : 3.654 img/sec; minFreeMem: 804Mb lwip.js : 1.203 img/sec; minFreeMem: 54Mb jimp.js : 0.445 img/sec; minFreeMem: 82Mb 
+6
Jul 13 '16 at 6:51
source share

If you do not need a large image, you can resize it on the client side before uploading it:

Reading files in JavaScript using file APIs

Client side image resizing using javascript before uploading to server

Many users can have a good idea of ​​themselves from a smartphone, and many of them are more than 200 KB. Please note that the data provided by the client should not be trusted, so server-side checks are still applied.

+3
Jun 04
source share

I used lwip (as arvind previously suggested), but switched to png-crop . This seems to work a little faster for me (Win 8.1 x64, Node v0.12.7). The code in the repo looks incredibly easy and quickly easy to use.

 var pngcrop = require('png-crop'); var config = {left: 10, top: 100, height: 150, width: 150}; pngcrop.crop('cats.png','cats-cropped.png',config); 

Of course, these will be only png files ...

+1
Aug 25 '15 at 10:09
source share

Sharp works very well and is easy to use with streams, it works like a charm, but you need to compile it with the version of the node, this is its drawback. I used Sharp to process images with an image from the AWS S3 recycle bin and worked fine, but I had to use a different module. GM didn't work for me, but Jimp worked really well!

You should pay attention to the path of the written picture, this can lead to errors if you start the path with "/".

This is how I used Jimp in nodeJS:

 const imageUrl = 'SOME_URL'; let imgExported = 'EXPORTED_PIC.png'; Jimp.read(imageUrl) .then(image => { image .resize(X, Y) .write('tmp/'+ imgExported, err => { if(err) console.error('Write error: ', err); else { ... // don't forget to put a callback() } } }); 

Also keep track of the execution order, set a callback so that other things don't happen when you don't want to. I tried using "await" for Jimp.read (), but that did not help.

0
May 15 '19 at 9:17
source share

You can do this using jimp (node_module)

Local Record:

 Jimp.read(path) // this can be url or local location .then(image=> { image .resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd .write('path-to-save'); }) .catch(err => { console.log(err); }); 

To download to s3 or anywhere.

 Jimp.read(urls) // this can be url or local location .then(image=> { image .resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd .getBase64(Jimp.AUTO, (err, res) => { const buf = new Buffer( res.replace(/^data:image\/\w+;base64,/, ""), "base64" ); var data = { Key: key, Bucket: bucket, Body: body, ContentEncoding: "base64", ContentType: "image/jpeg" }; s3.putObject(data, function(err, data) { if (err) { throw err; } else { console.log("succesfully uploaded the image!"); } }); }); }) .catch(err => { console.log(err); }); 
0
Sep 02 '19 at 13:51
source share



All Articles