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

AWS Lambda Node环境下FabricJS生成Data URI图片自定义字体不生效

问题:AWS Lambda运行Node后端调用FabricJS生成图片时自定义字体不生效

在AWS Lambda环境中运行Node后端,基于FabricJS画布生成图片,除画布中文本框的fontFamily属性不生效外,其余功能运行正常。

目录结构

字体文件存放在src目录下的fonts文件夹中,结构如下:

src
|----fonts
     |----fabric.conf
     |----Source
          |----SourceSansPro-Regular.otf
          |----SourceSansPro-Semibold.otf

已完成配置

fonts.conf配置

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
   <dir>/var/task/fonts/</dir>
   <cachedir>/tmp/fonts-cache/</cachedir>
   <config></config>
</fontconfig>

环境变量配置

FONTCONFIG_PATH="/var/task/fonts"
FONTCONFIG_FILE="/var/task/fonts/fonts.conf"

核心代码

字体注册与画布逻辑

const { fabric } = require('fabric')

fabric.nodeCanvas.registerFont('fonts/Source/SourceSansPro-Regular.otf', {family: 'Source Sans Pro'})
fabric.nodeCanvas.registerFont('fonts/Source/SourceSansPro-Semibold.otf', {family: 'Source Sans Pro Semibold'})

const canvas = new fabric.Canvas('canvas', {})

canvas.loadFromJSON(canvasJson, async () => {
    ...
    canvas.renderAll()
    const dataURL = canvas.toDataURL({
        width: canvas.width,
        height: canvas.height,
        left: 0,
        top: 0,
        format: 'png'
    })
    console.log(dataURL)
})

画布JSON配置片段

"objects": [
    ...
    {
        "shadow": null,
        ...
        "type": "textbox",
        ...
        "fontFamily": "Source Sans Pro Semibold",
        ...
    },
    ...
]

现象

最终导出的图片中仅显示默认字体,指定自定义字体未生效:
字体显示效果1
字体显示效果2


解决方案

1. 修正字体注册路径

AWS Lambda部署后代码运行根目录为/var/task,相对路径容易因工作目录偏移找不到字体文件,改为绝对路径注册:

const path = require('path')
// 按你实际代码目录层级调整路径拼接规则
fabric.nodeCanvas.registerFont(path.resolve(__dirname, './fonts/Source/SourceSansPro-Regular.otf'), {family: 'Source Sans Pro'})
fabric.nodeCanvas.registerFont(path.resolve(__dirname, './fonts/Source/SourceSansPro-Semibold.otf'), {family: 'Source Sans Pro Semibold'})

2. 强制刷新文本对象样式

FabricJS加载JSON时可能存在样式缓存未更新的问题,加载完成后遍历所有文本对象标记重绘:

canvas.loadFromJSON(canvasJson, async () => {
    // 遍历所有文本类对象强制更新
    canvas.getObjects().forEach(obj => {
        if (['text', 'textbox', 'itext'].includes(obj.type)) {
            obj.dirty = true
        }
    })
    canvas.renderAll()
    // 后续导出逻辑不变
})

3. 排查打包配置

确认项目打包工具(Webpack/ESbuild等)配置了静态资源拷贝规则,完整将fonts目录拷贝到部署包对应路径下,避免部署后字体文件丢失。

4. 清理fontconfig缓存

Lambda冷启动阶段先清理旧的字体缓存,避免缓存导致的字体加载失败:

const fs = require('fs/promises')
await fs.rm('/tmp/fonts-cache', { recursive: true, force: true })
await fs.mkdir('/tmp/fonts-cache', { recursive: true })

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:48:03