node-canvas 中的 registerFont() 未解析 Firebase Cloud Functions 上的字体

Posted

技术标签:

【中文标题】node-canvas 中的 registerFont() 未解析 Firebase Cloud Functions 上的字体【英文标题】:registerFont() from node-canvas not parsing font on Firebase Cloud Functions 【发布时间】:2021-11-12 08:22:39 【问题描述】:

我目前正在通过 Firebase Cloud Functions 使用node-canvas 生成图像,然后使用nodemailer 将其作为电子邮件附件发送。

图像的要求是我需要将一些字符串输入到具有特定字体的模板中。

所以在 Firebase Cloud Functions 上,这就是我所做的:

exports.test = functions.https.onRequest((request, response) => 
  cors(request, response, () => 
      let tempFilePath = path.join(os.tmpdir(), 'tnr.ttf');
      functions.logger.log('tempFilePath is', tempFilePath);

      bucket.file('tnr.ttf').download(destination: tempFilePath);
      functions.logger.log('Font downloaded locally to', tempFilePath);

      registerFont(path.resolve(tempFilePath), family: 'tnr');
      functions.logger.log('Font registered successfully');
  

我已经反复验证文件'tnr.ttf' 存在于我的项目云中,并且可以成功加载到该临时路径。

然而,在registerFont 函数中,无论我使用哪种字体文件,Firebase 都会抛出此错误:

Error: Could not parse font file
    at registerFont (/workspace/node_modules/canvas/index.js:48:17)

Firebase 处理这个包或函数的方式可能有问题吗?

【问题讨论】:

【参考方案1】:

您正在尝试在下载完成之前使用该字体。当你意识到问题时,打开一个终端并确认它确实存在,下载已经完成。

您需要做的是等待 download(...) 返回的 Promise 解决或将回调附加到 download() 方法。下载完成后就可以注册字体了。

exports.test = functions.https.onRequest((request, response) => 
  cors(request, response, (corsErr) => 
    if (corsErr) 
      // this is rare, but still possible.
      functions.logger.error('Request rejected by CORS: ', corsErr);
      res.status(412).send('Rejected by CORS'); // 412 FAILED PRECONDITION
      return;
    

    let tempFilePath = path.join(os.tmpdir(), 'tnr.ttf');
    functions.logger.log('tempFilePath is ', tempFilePath);

    bucket.file('tnr.ttf').download(
      destination: tempFilePath,
      (err) => 
        if (err) 
          functions.logger.error('Failed to download font to local system: ', err);
          res.status(422).send('Failed to register font'); // 422 UNPROCESSABLE ENTITY
          return;
        

        functions.logger.log('Font downloaded locally to ', tempFilePath);

        registerFont(path.resolve(tempFilePath), family: 'tnr');
        functions.logger.log('Font registered successfully');

        res.send('Registered font successfully');
      
    );
  

注意事项:

不要忘记正确处理错误并正确终止请求。 可能会再次调用相同的函数调用,请考虑在某处设置“我已下载该”标志。在“最坏的情况”下,您最终可能会得到 100 个相同的字体文件。 确保在您将使用它的地方执行registerFont 方法。您不能有单独的 /registerFonts/drawWithFont 端点,因为不能保证您正在与刚才的同一个函数实例进行通信。

【讨论】:

以上是关于node-canvas 中的 registerFont() 未解析 Firebase Cloud Functions 上的字体的主要内容,如果未能解决你的问题,请参考以下文章

使用 node-canvas 和 jsdom 重复调用资源

记录在Windows下安装node-canvas遇到的各种问题(无法安装canvas,安装canvas包报错error...)

更新node.js和Electron后,node-canvas失败

节点画布:使用自定义字体

Cordova 推送通知 - 注册标签

Nodejs找不到模块'../build/Release/canvas'