3

I'm trying to do some cropping using graphicsmagick and cfs and save the result to S3 (cfs:gridfs, cfs:graphicsmagick and cfs:s3).

The cropped image should be stored to three stores (main, public and thumbnail) - the stores itself have some transformWrite functions. So I thought I have to create a temp stream for doing this, but I failed to create this temp stream. I need some help for that.

I'm using the gridFS, no filesystem

var file     = Media.findOne({ _id: fileId }),
    read     = file.createReadStream('main');

gmread = gm(read)
    .crop(selection.w, selection.h, selection.x, selection.y)
    .stream();

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

    // create a temp stream
    var tmpread = fs.createReadStream(filename); // <-- MY PROBLEM

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

    // set cropped image to main store
    var write = file.createWriteStream('main');
    tmpread.pipe(write);

    // set public store image
    var writePublic = file.createWriteStream('public');
    gm(tmpread).stream().pipe(writePublic);

    // set thumbnail image
    var writeThumbnail = file.createWriteStream('thumbnail');
    gm(tmpread).stream().pipe(writeThumbnail);

}));

gmread.pipe(temp);
user3142695
  • 15,844
  • 47
  • 176
  • 332

2 Answers2

0

Actually you don't need to create the temp stream to do this, you can just use the transformWrite functions. Also you don't need to use those event listeners, here is an working example that I use in my project

var profilePictureResize = function(fileObj,readStream,writeStream){
    gm(readStream,fileObj.name()).resize('76','76^').gravity('Center').extent('76', '76').stream().pipe(writeStream);
}
var previewResize = function(fileObj,readStream,writeStream){
    gm(readStream,fileObj.name()).resize('240','160^').gravity('Center').extent('240', '160').stream().pipe(writeStream);
}
Images = new FS.Collection("images", {
    stores: [
        new FS.Store.FileSystem("images"),
        new FS.Store.FileSystem("profileSize",{transformWrite: profilePictureResize}),
        new FS.Store.FileSystem("previewSize",{transformWrite: previewResize})
    ],
    // permit only images here
    filter: {
        allow: {
            contentTypes: ['image/*']
        }
    }
});
  • But what I need to do create something like an image editor: If I click a button, there should be done a crop (example), for another button there is another action. And this should then be done for every store. That's why I do the manipulation first and then writeStream to the store... – user3142695 Mar 29 '16 at 07:19
0

I'm not sure if I understand your problem correctly, but you could use a PassThrough stream that you write the result to once.

Marcel Klehr
  • 884
  • 8
  • 9