6

I am trying to do some image manipulation via gm in collectionFS, because I need to read a stream and write it back to the same file, I have to use a temp-file - like shown below.

I want to check if the image is wider than 1000px. In this case it should be re-sized to 1000px.

Unfortunately this doesn't work, as I got the errors TypeError: Object [object Object] has no method 'pipe' and Error: gm().stream() or gm().write() with a non-readable stream.

var fs       = Npm.require('fs'),
    file     = Images.findOne({ _id: fileId }),
    read     = file.createReadStream('public'),
    filename = '/tmp/gm_' + Date.now(),
    temp     = fs.createWriteStream(filename);

if (method == 'resize') {
    // resize to 1000px, if image is bigger
    gmread = gm(read);
    gmread.size(function(err, size){
        if(size.width > 1000) {
            gmread.resize('1000').stream();
        }
    });
}

gmread.on('end', Meteor.bindEnvironment(function (error, result) {
    if (error) console.warn(error);

    var tmpread = fs.createReadStream(filename);
        write   = file.createWriteStream('public');

    tmpread.on('end', Meteor.bindEnvironment(function (error, result) { 
        if (error) console.warn(error);
    }));

    tmpread.pipe(write);
}));

gmread.pipe(temp);
Ashish Awasthi
  • 1,484
  • 1
  • 19
  • 34
user3142695
  • 15,844
  • 47
  • 176
  • 332
  • Are you using cfs:graphicsmagick? – Ivan Nov 28 '15 at 16:32
  • Does `gm.isAvailable()` return true? If not, then there are no binaries on the system for gm to actually work. – Ivan Nov 28 '15 at 16:34
  • Yes, gm is working well, as I can do a simple crop or something like that. But I'm not very familiar with gm, so I don't know how to do that resize, as it leads to a nested function... If I do just `resize('1000')` it works. – user3142695 Nov 28 '15 at 16:35

2 Answers2

2

I think the correct way in collectionFS is something like this:

var gmread = gm(readStream, fileObj.name());
gmread.size({bufferStream: true}, FS.Utility.safeCallback(function (error, size) {
    if (error) console.warn(error);
    else {
        if(size.width > 1000) gmread.resize('1000').stream().pipe(writeStream);
    }
}));

Mybe you want to put that into a transformWrite-function for your store...

user3848987
  • 1,627
  • 1
  • 14
  • 31
0

You can let GraphicsMagick do the test. Try

gmread.resize('1000x50000>');

instead of

gmread.size(function(err, size){
    if(size.width > 1000) {
        gmread.resize('1000').stream();
    }

See the GraphicsMagick "geometry" page.

Glenn Randers-Pehrson
  • 11,940
  • 3
  • 37
  • 61