问题
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!
回答1:
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.
回答2:
The problem is that you're trying to read the file before it's written. If you don't need to save the original image, you could just stream the file directly to gm instead:
req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
console.log('\n\nUploading file: '.underline.bold +filename .underline.bold);
console.log('Resizing file...');
gm(file, filename)
.resize('200','200')
.write('www/uploads/' + filename, function(err) {
if (err) throw err; // handle better
console.log('Success!'.bold);
});
});
You should probably also check that the given mime type of the file matches what you expect (e.g. image/jpeg
, image/png
, etc). You could also take that a step farther by using something like mmmagic to check the file type. However with mmmagic, you would have to forgo the direct streaming to gm option and save the file to disk first.
来源:https://stackoverflow.com/questions/23860390/express-graphicsmagick