nextjs + sharp在 vercel 环境svg转png出现中文乱码

在之前一篇博客 Next.js和sharp实现占位图片生成工具,详细介绍了使用 Next.js + sharp + Vercel 来实现一个 占位图片生成工具,遇到一个奇怪的问题:在本地开发环境,英文、数字、中文字符自定义内容,都能正常渲染。但是发布到 Vercel 生产环境,自定义内容除了英文字符和数字外,中文字符 显示为 Unicode 码位(乱码),如下图所示。

svg转png中文乱码

问题原因

经过排查,发现是 sharp 库在 vercel 生产环境下,对 svgpng 时,中文字符 会出现乱码。而在本地开发环境,sharp 库对 svgpng 时,中文字符 不会出现乱码。
vercel 平台查看 log 日志,发现了错误提示:Fontconfig error: No writable cache directories
进一步定位,说明是 vercel 容器环境没有支持中文的字体,因此无法正常渲染中文字符。

解决方案

  1. nextjs 项目根目录下,创建 fonts 文件夹,将中文字体文件 NotoSansSC-Regular.ttf 放入 fonts 文件夹中。我这里使用的是 NotoSansSC-Regular.ttf 字体,支持简体中文字符。下载地址:https://github.com/notofonts/noto-cjk
  2. fonts 文件夹下,创建 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>
  1. sharp 处理 svgpng 函数所在文件的头部加入如下代码:
resolve(process.cwd(), 'fonts', 'fonts.conf')
resolve(process.cwd(), 'fonts', 'NotoSansSC-Regular.ttf')
  1. 在项目根目录下创建一个 .env 环境变量文件,内容如下:
FONTCONFIG_PATH=/var/task/fonts
  1. svg 中设置 font-family,如下:
function getSvgBuffer({ w, h, bg, color, size, text }) {
  let textY = (+h + size / 2) / 2
  let svg = `
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs"
    width="${w}" height="${h}">
    <rect width="${w}" height="${h}"
    fill="${bg}" style="fill:${bg};"/>
    <text x="50%" y="${textY}" 
    style="font-family: 'Noto Sans', 'Noto Sans SC', sans-serif;"
    dominant-baseline="alphabetic" text-anchor="middle" 
    stroke="none" stroke-width="0" 
    font-size="${size}" fill="${color}" 
    fill-opacity="1">${text}</text>
</svg>`
  svg = '<?xml version="1.0" encoding="UTF-8"?>' + svg
  return Buffer.from(svg, 'utf-8')
}
  1. vercel 平台上配置环境变量 FONTCONFIG_PATH,值为 /var/task/fonts

FONTCONFIG_PATH

  1. 再次发布到 vercel 平台,问题解决。

参考文档:

  • https://sharp.pixelplumbing.com/install#fonts
  • https://github.com/lovell/sharp/issues/3698
  • https://github.com/lovell/sharp/issues/1875

欢迎访问:天问博客

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,Vercel是一个支持多种语言的云函数和静态网站托管平台,包括Java。你可以使用Vercel来托管你的Java应用程序。以下是使用Vercel托管Java应用程序的步骤: 1. 在本地创建一个Java应用程序,并确保它可以在本地运行。 2. 在Vercel上创建一个新项目,并将你的Java应用程序上传到该项目中。 3. 在Vercel上配置你的Java应用程序的环境变量和其他设置。 4. 部署你的Java应用程序并在Vercel上查看它。 以下是一个使用Vercel托管Java应用程序的示例: 1. 在本地创建一个Java应用程序,并确保它可以在本地运行。例如,创建一个名为"HelloWorld"的Java应用程序,其中包含以下代码: ```java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } ``` 2. 在Vercel上创建一个新项目,并将你的Java应用程序上传到该项目中。你可以使用Vercel的CLI工具来上传你的应用程序。首先,安装Vercel CLI工具: ```shell npm install -g vercel ``` 然后,使用以下命令将你的应用程序上传到Vercel: ```shell vercel deploy path/to/your/app ``` 3. 在Vercel上配置你的Java应用程序的环境变量和其他设置。你可以在Vercel的控制台中配置环境变量和其他设置。例如,你可以设置JAVA_HOME环境变量来指定Java的安装路径。 4. 部署你的Java应用程序并在Vercel上查看它。使用以下命令在Vercel上部署你的应用程序: ```shell vercel --prod ``` 然后,你可以在Vercel的控制台中查看你的应用程序,并在浏览器中访问它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值