node.js - Node JS Sharp - 转换为 JPG 时保持 SVG 字体

标签 node.js svg image-manipulation sharp

我正在使用 Sharp 库创建动态 JPEG 车牌图像。

基本上,我有一个 PNG,它是一个没有数字的虚荣车牌。然后我用这样的代码创建一个 svg

    const svg = new Buffer(
        `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${x} ${y} 500 40">
            <defs>
            <style type="text/css">
                <![CDATA[
                    @font-face {
                        font-family: LicensePlate;
                        src: url('LicensePlate.ttf');
                    }
                    svg {
                        width: 100%;
                        height: 100%;
                    }
                ]]>
            </style>
            </defs>

            <text x="0" y="0" font-family="LicensePlate" font-size="${fontsize}" letter-spacing="${letterspace}">
                ${platenumber.toUpperCase()}
            </text>
        </svg>`
    );

传入所需的宽度、高度和车牌号。然后我使用 Sharp 库将 SVG 覆盖在车牌中间。这一切都运行得很好。

但是,我导入了自定义车牌字体 (LicensePlate.ttf)。为了调试我的代码内 SVG 图像,我制作了一个实际的 svg 图像文件,在浏览器中打开该文件以确保它看起来正确,事实也确实如此。

问题是,当创建最终的 JPEG 文件时,它不包含我的自定义字体。相反,它依赖于 Verdana。

我的问题是,有什么方法可以在使用 Sharp 创建图像的同时保留 SVG 字体吗?

谢谢!

完整代码

function createImage(platenumber) {
    //Trying to create some sort of responsiveness
    let fontsize = 80;
    let letterspace = 10;
    let width = 300;
    let height = 90;
    let x = 0;
    let y = -45;

    const inputlength = platenumber.length;

    //Minumum Length
    if (inputlength == 2) {
        x = -200;
    }
    if (inputlength == 3) {
        x = -150;
    }
    if (inputlength == 4) {
        x = -130;
    }
    if (inputlength == 5) {
        x = -105;
    }
    if (inputlength == 6) {
        x = -65;
    }


    try {
        console.log('stream is duplex, ', pipe instanceof stream.Duplex);
        //Read the svg code into a buffer with a passed in plate number
        const svg = new Buffer(
            `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${x} ${y} 500 40">
                <defs>
                <style type="text/css">
                    <![CDATA[
                        @font-face {
                            font-family: LicensePlate;
                            src: url('LicensePlate.ttf');
                        }
                        svg {
                            width: 100%;
                            height: 100%;
                        }
                    ]]>
                </style>
                </defs>

                <text x="0" y="0" font-family="LicensePlate" font-size="${fontsize}" letter-spacing="${letterspace}">
                    ${platenumber.toUpperCase()}
                </text>
            </svg>`
        );

        const plateid = rand.generate(10);

        //Create a write stream to a randomly generated file name
        const write = new fs.createWriteStream(`plates/${plateid}.jpg`);

        //Create the sharp pipeline
        const pipeline = pipe
            .overlayWith(svg, { gravity: sharp.gravity.center })//we center the svg image over the top of whatever image gets passed into the pipeline
            .jpeg();//we convert to JPG because it is a compressed file format and will save space (we could also do webp if we really want to be slick about it)

        //Create the read stream from the license plate template
        const read = new fs.createReadStream('plate-2.png')
            .pipe(pipeline)//pipe out sharp pipeline
            .pipe(write);//add the write stream so that our sharp pipeline knows where to put the image

        return plateid;
    } catch (e) {
        console.log(e);
        return null;
    }
}

SVG 图像

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="90" viewBox="0 -50 500 40">
  <defs>
    <style type="text/css">
      <![CDATA[
        @font-face {
          font-family: LicensePlate;
          src: url('LicensePlate.ttf');
        }
      ]]>
    </style>
  </defs>

  <text x="0" y="0" font-family="LicensePlate" font-size="150" letter-spacing="10">
    Pl@T3#
  </text>
</svg>

精确字体

这是我使用的确切字体的链接 http://www.fontspace.com/dave-hansen/license-plate

最佳答案

我通过在操作系统中安装字体来解决这个问题,当文件转换时,库只能访问操作系统字体。

关于node.js - Node JS Sharp - 转换为 JPG 时保持 SVG 字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49289911/

相关文章:

javascript - 谁能解释一下为什么我们使用公共(public)文件夹来保存 css 和图像文件夹?

c++ - 如何将 Node.js 解释器嵌入到 C/C++ 中?

javascript - browserify 需要 -g 模块

vb.net - 在 VB.NET 中调整图像大小

node.js - Lambda 根据 zip 的创建方式抛出错误

javascript - SVG 模式,任何方式/黑客停止重复图像

javascript - D3.js 气泡图中消失的气泡

javascript - 从外部文件将 svg 路径加载到 DOM 中

c# - 如何在 ASP.NET Core 中上传文件?

algorithm - 手动将 RGBA 像素与 RGB 像素进行 alpha 混合