GeekyGautam
GeekyGautam

Reputation: 11

Download Image File after Jimp Processed the Image

I have this home route. In this home route I am using the Jimp library to process the image resize it and then change the quality and lastly save the image in the directory but I wanted to download the image so that user can download it on his machine. But it not downloading. I is correctly saving in the directory with the name output.jpg. Here is the code

app.get("/", (req, res) => {

res.type('jpg'); res.attachment('output.jpg')

jimp.read('lenna.png', (err, lenna) => { if (err) throw err; lenna .resize(256, 256) // resize .quality(60) // set JPEG quality .greyscale() // set greyscale .write('output.jpg'); // save

res.download('output.jpg'); });

Upvotes: 1

Views: 5038

Answers (1)

Nisatru
Nisatru

Reputation: 35

When trying to reproduce your error I get a jpg file downloading in the browser when sending a request to the node server but this file seems to be faulty. The reason for this is that jimp.write() is an asynchronous function and therefore

res.download('output.jpg')

is executed before jimp.write() is done writing the file to the disk. To send your file after the file is fully written to disk you have two options to use jimp.write which are documented here

Here is my quick code to reproduce and fix the problem

Using jimp.write with a callback

const express = require('express')
const app = express()
var jimp = require('jimp');

app.get("/", (req, res) => {
    res.type('jpg');
    res.attachment('output.jpg');
    jimp.read('lenna.png', (err, lenna) => {
        if (err) throw err; 
        lenna.resize(256, 256) // resize
        .quality(60) // set JPEG quality
        .greyscale() // set greyscale
        .write('output.jpg', res.download('output.jpg')); // save
    });
});

app.listen(3000);

The important line is to put your res.download() in the callback of jimp.write() which executes when jimp is done writing the file to your disk.

.write('output.jpg', res.download('output.jpg')); // save

Using jimp.writeAsync which returns a promise

const express = require('express')
const app = express()
var jimp = require('jimp');

app.get("/", (req, res) => {
    res.type('jpg');
    res.attachment('output.jpg');
    jimp.read('lenna.png', async (err, lenna) => {
        if (err) throw err; 
        await lenna.resize(256, 256) // resize
        .quality(60) // set JPEG quality
        .greyscale() // set greyscale
        .writeAsync('output.jpg'); // save
        res.download('output.jpg');
    });
});

app.listen(3000);

Using async and await until lenna.(...).writeAsync('output.jpg') is done and resolves the returned promise

Upvotes: 3

Related Questions