1

I recently switched from Canvas to Sharp to create the welcome image that pops up in the welcome channel every time a user joins since I heard that Sharp is more faster than Canvas. I didn't have any error when I was using Canvas, but in Sharp I got stuck in trying to load the user's avatar image on the welcome image. Every time I run this code, an error comes saying Error: Expected width, height and channels for raw pixel input. I am able to bring some text in the image but nothing else. My Code =>

async function addTextOnImage() {
  try {
    const width = 1024;
    const height = 500;
    const usernameText = `Hello ${member.user.tag}`;
    const memberCountText = `You are member ${member.guild.memberCount}`;
    const username = `
      <svg width="${width}" height="${height}">
          <style>
              .username { fill: #4ceb34; font-size: 60px; font-weight: bold;}
          </style>
          <text x="50%" y="50%" text-anchor="middle" class="username" font-family='Readex Pro'>${usernameText}</text>
      </svg>
      `;
    const memberCount = `
      <svg width="${width}" height="${height}">
          <style>
              .memberCount { fill: #4ceb34; font-size: 40px; font-weight: bold;}
          </style>
           <text x="50%" y="50%" text-anchor="middle" class="memberCount" font-family='Readex Pro'>${memberCountText}</text>
      </svg>
      `;
    const usernameBuffer = Buffer.from(username);
    const memberCountBuffer = Buffer.from(memberCount);
    sharp("background.jpg")
      .resize(1024, 500)
      .composite([
        {
          input: usernameBuffer,
          top: 80,
          left: -10,
        },
        {
          input: memberCountBuffer,
          top: 130,
          left: -10,
        },
        {
          input: sharp(member.user.displayAvatarURL()),
          top: 50,
          left: -10,
        },
      ])
      .toFile("./events/output.jpeg", (err, info) => {
        if (err) throw err;
        const attachment = new DJS.MessageAttachment("./events/output.jpeg");
        welcomeChannel.send({
          content: content,
          files: [attachment],
        });
      });
  } catch (error) {
    console.log(error);
  }
}
addTextOnImage();

The image comes like this =>

welcome image example

Thanks!

Edit:

I actually found a way to do this by using the axios module and doing this =>

const composite = (await axios({ url: member.user.displayAvatarURL(), responseType: "arraybuffer" })).data

But is there any faster or better way to do this since it takes axios some time to fetch it?

Caladan
  • 2,261
  • 2
  • 6
  • 19
  • ‘it takes axios some time to fetch it’ There isn’t really a much better way as the main factor for this being slow is the network request — you will always have to fetch the image data. – Lauren Yim May 28 '22 at 06:57
  • Yeah, that's why I wanted to check if there was any alternative to using `axios` – Caladan May 28 '22 at 06:59
  • There’s undici, node-fetch, got, superagent, etc. Just do a quick search for Node.js request libraries and you’ll find a lot of alternatives. – Lauren Yim May 28 '22 at 09:36

0 Answers0