使用 canvas 在圆圈内绘制图像

Drawing an image inside a circle using canvas

我一直在尝试使图像在 canvas 绘制的圆圈内居中,该圆圈在页面中间居中,但我想在其中绘制的图像不能。

const background = await Canvas.loadImage(`./backgrounds/${UserJSON[message.author.id].background}.png`);
        const canvas = Canvas.createCanvas(250, 400);
        const context = canvas.getContext('2d');
        context.drawImage(background, 0, 0, canvas.width, canvas.height);


        context.strokeStyle = '#0099ff';
        context.strokeRect(0, 0, canvas.width, canvas.height);

        context.font = '28px sans-serif';
        context.fillStyle = '#ffffff';
        context.fillText(`${message.author.username}`, canvas.width / 4, canvas.height / 1.6);

        context.beginPath();
        context.arc(canvas.width / 2, canvas.height / 2, 70, 0, Math.PI * 2, true);
        context.closePath();
        context.clip();

        const avatar = await Canvas.loadImage(message.author.displayAvatarURL({ format: 'jpg', size: 4096 }));
        context.drawImage(avatar, 0, 0, 250, 320);


        const attachment = new MessageAttachment(canvas.toBuffer(), 'profile-image.png');

我不知道我在“drawImage”上做错了什么,我似乎无法将图像最小化以适合圆圈或其他任何东西。下面我把我的 discord 头像和它在 canvas

上的绘制方式

你需要自己做一些计算。 drawImage 将采用位图并将其投影到您给它的任何矩形上(不会保持纵横比)。因此,您需要进行所有 centercover 计算。

const canvas = Canvas.createCanvas(250, 400);
const context = canvas.getContext('2d');
context.fillStyle = '#6f6f6f';
context.fillRect(0, 0, canvas.width, canvas.height);

const circle = {
    x: canvas.width / 2,
    y: canvas.height / 2,
    radius: 70,
}

context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2, true);
context.closePath();
context.clip();

const avatar = await Canvas.loadImage('./image.jpg');
console.log(avatar.height, avatar.width);

// Compute aspectration
const aspect = avatar.height / avatar.width;
// Math.max is ued to have cover effect use Math.min for contain
const hsx = circle.radius * Math.max(1.0 / aspect, 1.0);
const hsy = circle.radius * Math.max(aspect, 1.0);
// x - hsl and y - hsy centers the image
context.drawImage(avatar,circle.x - hsx,circle.y - hsy,hsx * 2,hsy * 2);