Search code examples
javascriptnode.jsexpressgraphicsmagick

Express GraphicsMagick


I'm currently building a MEAN app and the section I'm currently working on involves image uploads. I'm trying to use GraphicsMagick for Node but I'm not really having any success. Below is my POST request for image uploads (as is):

app.post('/api/users/upload_image', function (req, res) {
        var fstream;
        req.pipe(req.busboy);
        req.busboy.on('file', function (fieldname, file, filename) {
            console.log('\n\nUploading file: '.underline.bold +filename .underline.bold);


            // var readStream = fs.createReadStream(filename);
            // gm(readStream, readStream.path)
            //  .resize('200','200')
            //  .stream(function (err, stdout, stderr) {
            //      var writeStream = fs.createWriteStream('www/uploads/' + readStream.path);
            //      stdout.pipe(writeStream);
            //  });

            fstream = fs.createWriteStream('www/uploads/' + filename);
            file.pipe(fstream);

        });

        req.busboy.on('finish', function () {
            res.writeHead(303, { Connection: 'close', Location: '/' });
            res.end();
        });
    });

The commented out section is my attempt at using GM but that throws back the error: Error: ENOENT, open '[filename].jpg'

Where am I going wrong? This is my first try at using GM so I'm a newb to this library!


Solution

  • var readStream = fs.createReadStream(filename);
    

    at this line file named filename is not actually there yet you write that file below the commented lines. What you have is read steam named file you get from busyboy. so get rid of this line and pass file to gm directly

    gm(file,....
    

    Code below does exactly what you want, note the gm's write function's parameters.

    app.post('/api/users/upload_image', function (req, res) {
        req.pipe(req.busboy);
        req.busboy.on('file', function (fieldname, file, filename) {
            console.log('\n\nUploading file: '.underline.bold +filename .underline.bold);
    
            console.log('Resizing file...');
    
            gm(file,'www/uploads/' + filename)
            .resize(200,200)
            .write('www/uploads/' + filename, function (err) {
                console.log("finished");
            });
        });
    
        req.busboy.on('finish', function () {
            res.writeHead(303, { Connection: 'close', Location: '/' });
            res.end();
        });
    });
    

    Note that gm's resize when used this way, simply fit's image in 200x200 box, does not exactly rescale/stretch it to 200x200.

    If this still give you an error like EPIPE, your node process might not have sufficent permissions to write that file.