SVG 作为 SVG 的图像标签在与 sharp 一起使用时不起作用

SVG as SVG's image tag not working while using with sharp

我正在使用 sharp 转换文件,但 sharp 给了我一个空的 png 文件。

我想使用 base64 格式的 SVG 图像作为 <image> 标签的来源,并想将其转换为 png 文件。

这是一个展示我正在尝试做的事情的例子;

const sharp = require('sharp');
sharp(Buffer.from(<look below js file to see the SVG>))
    .toFormat('png')
    .toFile('output.png')

这里有一个 JS 来展示我尝试做的事情。基本上,我想使用 sharp 将此 SVG 转换为 png 文件,但 sharp 给我一个空的 png。

看起来sharp对外部图片的处理不是很好

您可以尝试 "flatten" SVG,然后再将其传递给 sharp

快速而肮脏的实施

这很容易出错。理想情况下,您会使用 Cheerio 之类的东西来解析和修改 SVG 输入。

它也仅保留 xywidthheightopacity 属性。其他属性需要进一步更改。

function flattenSVG (svg) {
  const images = svg.match(/<image [^>]+>/g);
  if (!images || images.length < 1) {
    return svg;
  }

  var result = svg;
  images.forEach(image => {
    const [,data] = image.match(/ xlink:href="data:image\/svg\+xml;base64,([^"]+)"/) || [];
    if (!data) {
      return;
    }

    const innerSVG = Buffer.from(data, 'base64').toString();
    const [,width] = image.match(/ width="([^"]+)"/) || [];
    const [,height] = image.match(/ height="([^"]+)"/) || [];
    const [,opacity] = image.match(/ opacity="([^"]+)"/) || [];
    const [,x] = image.match(/ x="([^"]+)"/) || [];
    const [,y] = image.match(/ y="([^"]+)"/) || [];
    const [header] = innerSVG && innerSVG.match(/<svg[^>]+>/) || [];
    const fixedHeader = header
      .replace(/ (x|y|width|height)="([^"]+)"/g, '')
      .replace('<svg', `<svg x="${x}" y="${y}" width="${width}" height="${height}" opacity="${opacity || 1.0}"`);
    const replacement = innerSVG && innerSVG.replace(header, fixedHeader);
    result = result.replace(image, replacement);
  });

  return result;
}

因此,在您的代码中,您将使用如下内容:

sharp(Buffer.from(flattenSVG(testSVG)))
      .toFormat('png')
      .toFile('output.png')

您可以在 Glitch.

检查工作代码(出于测试目的有点不同,因为它使用缓冲区而不是文件输出)