You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用node-canvas+TypeScript绘图触发cairo断言失败问题求助

Node-Canvas + TypeScript 触发 Cairo 哈希表断言错误的解决思路

问题场景

使用Node-Canvas绘制欢迎卡片时,通过ts-node运行TypeScript代码触发底层Cairo断言错误,已知相关修复方案但推测TypeScript编译/运行流程导致问题复现。

错误信息

Assertion failed: (tmp.table_size - hash_table_sizes < ARRAY_LENGTH (hash_table_sizes)), function _cairo_hash_table_manage, file cairo-hash.c, line 286.
/var/folders/ll/02j8nvys66176tszvw01w1c00000gq/T/start6586898863.sh: line 2: 17744 Abort trap: 6           ts-node src/index.ts

相关代码

import { Canvas } from 'canvas';
import { join } from 'path';

async function drawWelcomeCard(member: any) {
    const canvas = Canvas.createCanvas(1772, 633);
    const ctx = canvas.getContext('2d');

    // 注册字体
    Canvas.registerFont(join(__dirname, `../Fonts/Panton-BlackCaps.otf`), {
      family: 'Panton-BlackCaps',
    });
    Canvas.registerFont(join(__dirname, `../Fonts/coolvetica rg.otf`), {
      family: 'Coolvetica',
    });

    // 绘制背景图
    const background = await Canvas.loadImage(
      join(__dirname, `../Images/background.png`)
    );
    ctx.drawImage(background, 0, 0, canvas.width, canvas.height);

    // 获取用户信息
    const username = `${member.user.username}#${member.user.discriminator}`;
    const avatar = await Canvas.loadImage(
      member.user.displayAvatarURL({ format: 'jpg' })
    );

    // 绘制圆形头像
    ctx.beginPath();
    ctx.arc(322, 280, 208, 0, Math.PI * 2, true);
    ctx.closePath();
    ctx.shadowColor = '#000000';
    ctx.shadowBlur = 16;
    ctx.clip();
    ctx.drawImage(avatar, 322, 280, 500, 500);

    // 根据用户名长度绘制文本
    if (username.length >= 14) {
      ctx.font = '70 px Coolvetica';
      ctx.fillStyle = '#ffffff';
      ctx.shadowColor = '#000000';
      ctx.shadowBlur = 7;
      ctx.fillText(username, 322.42, 546.79);
    } else {
      ctx.font = '93 px Coolvetica';
      ctx.fillStyle = '#ffffff';
      ctx.shadowColor = '#000000';
      ctx.shadowBlur = 7;
      ctx.fillText(username, 322.42, 546.79);
    }

    // 绘制欢迎标题
    ctx.font = '195.35 px Panton-BlackCaps';
    ctx.fillStyle = '#ffffff';
    ctx.shadowColor = '#000000';
    ctx.shadowBlur = 7;
    ctx.fillText('WELCOME!', 1177, 287.55);

    // 绘制副标题
    ctx.font = '99.71 px Coolvetica';
    ctx.fillStyle = '#ffffff';
    ctx.shadowColor = '#000000';
    ctx.shadowBlur = 7;
    ctx.fillText('Enjoy your stay!', 1177, 398.46);

    return canvas.toBuffer();
}

解决步骤

1. 升级Node-Canvas到修复版本

该Cairo哈希表问题已在Node-Canvas后续版本中修复,直接升级依赖:

npm install canvas@latest
# 或锁定到已知修复版本,比如canvas@2.8.0及以上

2. 调整代码执行顺序

将字体注册逻辑移到Canvas实例创建之前,避免Cairo初始化阶段出现哈希表冲突:

// 先注册字体
Canvas.registerFont(join(__dirname, `../Fonts/Panton-BlackCaps.otf`), {
  family: 'Panton-BlackCaps',
});
Canvas.registerFont(join(__dirname, `../Fonts/coolvetica rg.otf`), {
  family: 'Coolvetica',
});

// 再创建Canvas实例
const canvas = Canvas.createCanvas(1772, 633);
const ctx = canvas.getContext('2d');

3. 避免使用ts-node直接运行

ts-node的即时编译可能导致资源加载时机异常,建议先编译为JavaScript再运行:

  1. 执行TypeScript编译:
    tsc
    
  2. 运行编译后的代码:
    node dist/index.js
    
  3. 若需保留ts-node运行,清理其缓存:
    ts-node --clear-cache
    

4. 清理依赖缓存

删除旧依赖文件并重新安装,避免版本冲突:

rm -rf node_modules package-lock.json
npm install

内容的提问来源于stack exchange,提问作者bruhbruh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 23:45:36