1

Using nodejs, express, Jimp. I cannot get Jimp to ".print" to an image and ".writeAsync", or more accurately I think the problem is I cant ".loadFont" and ".read". I have tried using ".loadFont" both inside and outside of ".read" by nesting. I can only ever get the newly saved .png without the edits from ".print".

app.post('/invite/:email/:name', async (req,res) => {
  try {
    var email = atob(req.params.email);
    var name = atob(req.params.name);
    var data = req.body;
    const inviteImage = await makeImg(name, data);
   
  // working code for sending email with image attachment

  } catch (error) {
    return next(error);
  }
});


function makeImg(name, data) {
  return new Promise(resolve => {
    const font = Jimp.loadFont(Jimp.FONT_SANS_32_WHITE)
      .then(font => {
        return font;
      })
    Jimp.read('./imgs/casualTemplate.jpg')
      .then(image => {
        // Do stuff with the image.
        return image
          .print(font, 10, 10, `hello`)
          .writeAsync('./casualInvite.png');
      })
      .catch(err => {
        // Handle an exception.
        //return next(error);
      });
      resolve("casualInvite.png");
  });
}
    // some more code i have tried inside Promise, also tried mixing them
    /*
    const font = await Jimp.loadFont(Jimp.FONT_SANS_32_WHITE);
    const image = await Jimp.read('./imgs/casualTemplate.jpg');
    image.print(font, 10, 10, `hello`);
    await image.writeAsync('./casualInvite.png');
    resolve("casualInvite.png");
    */

I have been trying every method i can find on the internet all day.

Loom
  • 21
  • 2

1 Answers1

0

So I finally got it to work. I dont fully know why but it sounds like it has to do with an anti-pattern. With no changes made to the POST; I made my wrapping function Async and I moved the variable declaration with "await" before the Promise.

If anyone could put links or explain what is going on that would be great, i am quite new to the language.

async function makeImg(name, data) {
  // add await outside of promise
  let image = await Jimp.read('./imgs/casualTemplate.jpg');
  
  return new Promise(resolve => {
    
    Jimp.loadFont(Jimp.FONT_SANS_32_WHITE)
      .then(font => {
        image.print(font, 10, 10, `hello`);
        return image;
      }).then(image => {
        return image.writeAsync('./casualInvite.png');
      });

      resolve("casualInvite.png");
  });
}
Loom
  • 21
  • 2
  • 3
    There's no need for your `return new Promise(...)` wrapper. That is an anti-pattern. Just do `return Jimp.loadFont(...).then(...)`. It's an anti-pattern for a number of good reasons. Besides just wasted code, you also aren't handling errors properly whereas `return Jimp.loadFont(...).then(...)` returns promise rejections to the caller which is proper error handling. – jfriend00 Jan 21 '22 at 07:27