Sharp: overlayWith issue?

Created on 19 Jan 2019  路  4Comments  路  Source: lovell/sharp

I simplified the code for a bit to keep it readable.

I have a Telegram bot to whom I send a photo and expect to get it back watermarked. This is on a Debian machine with node.js, using Telegram (Telegram API wrapper).

Watermarking images with overlayWith works nicely (not all the time though) with small sized images. When I try it with a bigger image, it gets stuck at "Photo has been saved..".. no other errors.

I know my code it's a mixture of callbacks and promises and there might be a better way of rewriting this, however, I asked around and no one could find any faults of why is this happening so I am posting here as a last resort hoping someone can give me hand. I am thinking overlayWith is the issue here, or am I not using it correctly? Or is my sync/async mess of a code the issue?

const today = new Date();
const date = (today.getMonth() < 9 ? '0': '') + (today.getMonth()+1)+'-'+today.getDate(); 
const time = today.getHours() + ":" + today.getMinutes() + "." + today.getSeconds();
const dateTime = date+'--'+time;
const fileName = './temp/'+dateTime+'.jpg';
const watermarkedFile = './temp/DONE-'+dateTime+'.jpg';
bot.on('photo', (ctx) => {
  let photoId = ctx.message.photo.pop().file_id;
  let photo = Promise.resolve(ctx.telegram.getFile(photoId));

  ctx.reply('You sent a photo..');

  photo.then(async function(object) {
    const receivedFilePath = await "https://api.telegram.org/file/bot"+process.env.BOT_TOKEN+"/"+object.file_path;

    console.log('I saved it already..');

    https.get(receivedFilePath, res => {
      console.log('https.get started..');

      var savedFile = fs.createWriteStream(fileName);
      res.pipe(savedFile);
      savedFile.on('finish', () => {
        console.log("Photo has been saved..");

        sharp.cache(false);
        sharp(fileName).overlayWith('cross.png', { top: 10, left: 10 }).toFile(watermarkedFile, (err, info) => {
          if (err) {
            console.log(err);
          } else {
            console.log("sharp processed the image and the watermarkedPath is: " + watermarkedFile);

            bot.telegram.sendPhoto(testGroup, {
              source: watermarkedFile
            });

            console.log('I\'ve sent the photo back (watermarked)..');
          }
        });

      });
    });
  });
}); 
question

All 4 comments

Hello, a few thoughts:

  • if it's failing silently the various streams would benefit from some error handling (listen for the "error" event)
  • listen for the "close" rather than "finish" event on savedFile
  • there will be concurrency problems when writing everything to the same (const) watermarkedFile location

Thank you @lovell - your 3rd advice fixed it. This library is great, cheers!

@lovell If I pass a few photos through sharp (say 6 medium res), most of them are returned fine but some with errors.

Any tips of how to avoid this, please? Doing it one by one it's fine but not with multiple images.

In the code sample above, the fileName input is based on a timestamp so two files being processing within the same second will trash each other.

These sort of questions are unrelated to sharp and are more appropriate for StackOverflow - good luck!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

natural-law picture natural-law  路  3Comments

henbenla picture henbenla  路  3Comments

emmtte picture emmtte  路  3Comments

knoxcard picture knoxcard  路  3Comments

jaekunchoi picture jaekunchoi  路  3Comments