Node.js, Express, and GM (GraphicsMagick) - Adding watermarks and general image processing efficiency -



Node.js, Express, and GM (GraphicsMagick) - Adding watermarks and general image processing efficiency -

i need create 4 image sizes uploaded photo: large, medium, small, , small. it's working part code below, big , medium sizes need have watermark set in bottom left, not smaller 2 sizes.

it seems watermarked images, i'll need duplicate file stream , save out separate instance each one. speed , efficiency of import here, want create sure i'm doing best way.

the gm node module lacking in documentation. more info link graphicsmagick site, doesn't help if you're trying gm module. it's frustrating.

so basically, utilize help figuring out how watermarks on 2 larger sizes, , want know if code below efficient be. seems bit slow when creating 4 sizes on local machine.

var filename = req.files.photo.name, filebasename = filename.substr(0, filename.lastindexof('.')), uploadroot = siteconfig.root + '/upload/', photosroot = siteconfig.root + '/photos/', publicroot = siteconfig.root + '/public/'; require('fs').rename( req.files.photo.path, uploadroot + filename, function(error) { if (error) { res.send({ error: 'upload error' }); return; } var imagesizes = { large: { width: 990, height: 990 }, medium: { width: 550, height: 550 }, small: { width: 145, height: 145 }, xsmall: { width: 55, height: 55 } }; var gm = require('gm'), filestream = require('fs').createreadstream(photosroot + filename); var lgpath = photosroot + filebasename + '_lg.jpg', mdpath = photosroot + filebasename + '_md.jpg', smpath = photosroot + filebasename + '_sm.jpg', xspath = photosroot + filebasename + '_xs.jpg'; // i'm guessing sec parameter set format gm(filestream, 'img.jpg') .size( { bufferstream: true }, function(err, size) { console.log(size.width); console.log(size.height); if (size.width > imagesizes.large.width || size.height > imagesizes.large.height) this.resize(imagesizes.large.width, imagesizes.large.height); // auto-orient based on exif info remove exif info .autoorient() .noprofile() .quality(70) .write( lgpath, function (err) { if (!err) { console.log('write big done'); .resize(imagesizes.medium.width, imagesizes.medium.height) // watermark code - want go on using file stream instead of file path //.subcommand('composite') //.gravity('center') //.in('-compose', 'over', watermarkfilepath, basefilepath) .quality(70) .write( mdpath, function (err) { if (!err) { console.log('write medium done'); .resize(imagesizes.small.width, imagesizes.small.height) .crop(imagesizes.small.width, imagesizes.small.height) .quality(70) .write( smpath, function (err) { if (!err) { console.log('write little done'); .resize(imagesizes.xsmall.width, imagesizes.xsmall.height) .quality(70) .write( xspath, function (err) { if (!err) console.log('write xsmall done'); else console.log('write xsmall error'); } ); } else console.log('write little error'); } ); } else console.log('write medium error'); } ); } else console.log('write big error'); } ); } ); } );

(note not real code, thought real code might want like)

it strikes me want this:

server.on('incomingimage', function (image, res) { async.each(imageoptions, function (imageoptions, done) { image .pipe(resize(imageoptions)) .pipe(fs.createwritestream(basedir + image.path + imageoptions.path)) .on('end', done); }, function (err) { if (err) { res.send(500); } else { res.send(204); } }); });

which say, when image comes in, create resizing through stream , file writing stream each image option, pipe image through resizing streams on file writting streams, 1 time files have been written, respond.

by doing processing in parallel, streams, minimize wait time server have due io (which basic thought behind node.js in first place).

as writing file disk, processing each image alternative in turn , writing them disk before starting in on reading file disk yet again.

so that's write time x 1 + read time x 5 + process time x 5 + write time x 5

instead should max process time + max write time much shorter.

there complications since gm module doesn't provide nice stream interface. might want see if there's improve module.

also on topic of streams:

https://github.com/substack/stream-handbook http://nodeschool.io/#stream-adventure

and on async

http://nodeschool.io/#asyncyou

node.js graphicsmagick

Comments

Popular posts from this blog

php - Android app custom user registration and login with cookie using facebook sdk -

c# - Create a Notification Object (Email or Page) At Run Time -- Dependency Injection or Factory -

Set Up Of Common Name Of SSL Certificate To Protect Plesk Panel -