Search code examples
imagesails.jsgraphicsmagickskipper

Skipper in SailsJS (beta) image resize before upload


I'm using SailsJS (beta). I'm trying to find a way to use graphicsmagick to take the stream parsed by Skipper in SailsJS-beta to resize the image before calling the Skipper-function req.file('inputName').upload().

My goal is to take my large, original image, and resize it before uploading it. Sails beta have introduced the Skipper-file-parser which are poorly documented (at least I don't understand it). Please help me understand how to resize the image before upload.

This works (code in my controller action):

req.file('fileName').upload('storedImage.png', function(err, files){
  // File is now uploaded to storedImage.png
});

What I want is something like:

// Read the file stream into a file upload
var stream = req.file('fileName');

gm(stream).resize(200, 200).write('storedImage.png', function(err){
  // File is now resized to 200x200 px and uploaded to storedImage.png
});

My problem is: how do I properly fetch the stream from req.file('fileName') to send it to gm?


Solution

  • This should work for you:

    var Writable = require('stream').Writable;
    var resize = require('image-resize-stream')(100); // Or any other resizer
    
    // The output stream to pipe to
    var output = require('fs').createWriteStream('storedImage.png');
    
    // Let's create a custom receiver
    var receiver = new Writable({objectMode: true});
    receiver._write = function(file, enc, cb) {
      file.pipe(resize).pipe(output);
    
      cb();
    };
    

    Now in your action you just have to use your receiver:

    req.file('fileName').upload(receiver, function(err, files){
      // File is now resized to 100px width and uploaded to ./storedImage.png
    });
    

    I have a feeling that Skipper's API is going to change, a lot, but this will work for now (with v0.1.x).

    UPDATE

    Specifically, if using gm for resizing, it'll be something like this:

    var gm = require('gm');
    var Writable = require('stream').Writable;
    
    // The output stream to pipe to
    var output = require('fs').createWriteStream('storedImage.png');
    
    // Let's create a custom receiver
    var receiver = new Writable({objectMode: true});
    receiver._write = function(file, enc, cb) {
      gm(file).resize('200', '200').stream().pipe(output);
    
      cb();
    };