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
Post a Comment