I can't get my head around image processing in node js. Sadly AND gladly this will be an important part of my application.
What I am trying to achieve is the following:
1) User updloads an image (=> multipart formdata gets send to the server containing all data. This works great) 2) Resize that picture to a max width of 640px. 3) Crop that picture from Y-axis: some_variable to Y-axis some_variable + max_height (240) and X-axis: 0 to X-axis 640px 4) Save it like that on the server.
Here is my current miserable approach with multer and lwip
Example picture data:
Files { fieldname: 'picture_data',
originalname: 'dog-how-to-select-your-new-best-friend-thinkstock99062463.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'public/imgs/',
filename: '1-picture_data-1453136557949.jpg',
path: 'public/imgs/1-picture_data-1453136557949.jpg',
size: 1790149 }
This data gets received by my router in this function:
router.post('/someCall', upload.single('picture_data'), function(req, response) {
...
});
Now the multer upload function gets called:
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/imgs/');
},
filename: function (req, file, cb) {
// CHECK IF FILE IS TOO BIG
var fileSize = file.size;
File_controller.checkFeedPostFileSize(fileSize, function(err, res){
if(res == "File size ok"){
var mimeType = file.mimetype;
File_controller.checkMimeTypeImage(mimeType, function(err, res){
// FILE IS OK AND MAY BE SAVED.
if(res == "Mimetype ok"){
var ending = ".jpg";
if(mimeType == "image/jpeg"){
ending = ".jpg";
}else if(mimeType = "image/png"){
ending = ".png";
}
var filename = req.session.user.id + "-" + file.fieldname + '-' + Date.now() + ending;
req.session.user.file_name = filename;
cb(null, filename);
var path = 'public/imgs/' + req.session.user.filename;
lwip.open(path, function(err, image){
if (err) return console.log("LWIP BILD NICHT GEFUNDEN", err);
image.resize(640, function(){
});
});
}else{
//response.send("Error: Mimetype not ok");
}
});
}else{
//response.send("Error: File size too big");
}
});
}
});
Now that approach works until the lwip part. Which means the file gets saved to the server in its original upload size. As far as I understand the module lwip should now open the image from the server then resize it and save it again.
This approach is pretty awkward and I am sure it can be done right on the way before saving and reopening the file. But if you help me to get it to work in any way I'd be super thankful.
If any information is missing to solve this problem please let me know. I will not hesitate to include everything necessary.
Thank you
You should open the image in your router handler, which will be called once the file exists on the file system. Both options on diskStorage
are called prior to the file being fully uploaded. Remove the lwip part from filename
, and try something along the lines of this instead:
router.post('/someCall', upload.single('picture_data'), function(req, response) {
lwip.open(req.file.path, function(err, image){
image.batch()
.resize(640)
.writeFile('output.jpg', function(err){
if (err){
response.status(400).send({ error: err.toString() });
}
else {
response.status(200).end();
}
}
);
});
});