使用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再运行:
- 执行TypeScript编译:
tsc - 运行编译后的代码:
node dist/index.js - 若需保留ts-node运行,清理其缓存:
ts-node --clear-cache
4. 清理依赖缓存
删除旧依赖文件并重新安装,避免版本冲突:
rm -rf node_modules package-lock.json npm install
内容的提问来源于stack exchange,提问作者bruhbruh
相关产品推荐
相关产品推荐

