看起来sharp 不能很好地处理外部图像。
您可以在将 SVG 传递给 sharp 之前尝试“扁平化”它。
快速而肮脏的实现
这很容易出错。理想情况下,您会使用 Cheerio 之类的东西来解析和修改 SVG 输入。
它还仅保留 x、y、width、height 和 opacity 属性。其他属性需要进一步更改。
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 处检查工作代码(出于测试目的,它使用缓冲区而不是文件输出,因此略有不同)。