我有一个无服务器功能,该功能基于作为查询参数发送的文本返回SVG。
module.exports = (req, res) => {
const { yourName } = req.query;
res.setHeader("Content-Type", "image/svg+xml");
const svg = `
<svg fill="none" viewBox="0 0 600 400" width="600" height="400" xmlns="http://www.w3.org/2000/svg">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">
<style>
.title {
font-size: 10vh;
font-weight: regular;
background-color: #ffddff;
}
</style>
<p class="title">Hello ${yourName}</p>
</div>
</foreignObject>
</svg>
`;
res.send(svg);
};
例如,当我调用/api?yourName=world
时,它将返回以下SVG;
(部署的URL:https://vercel-test-ruddy.vercel.app/api?world)
我需要将SVG作为图像(PNG / JPEG)返回。 所以,我的函数看起来像
module.exports = (req, res) => {
const { yourName } = req.query;
res.setHeader("Content-Type", "image/png");
const svg = `
<svg fill="none" viewBox="0 0 600 400" width="600" height="400" xmlns="http://www.w3.org/2000/svg">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">
<style>
.title {
font-size: 10vh;
font-weight: regular;
background-color: #ffddff;
}
</style>
<p class="title">Hello ${yourName}</p>
</div>
</foreignObject>
</svg>
`;
res.send( svgToPng(svg) );
};
svgToPng = (svg) => {
// not defined
}
是的。关于将SVG转换为PNG的问题很少:
Convert SVG to image (JPEG, PNG, etc.) in the browser
How to Exporting SVG as PNG format
几乎每个答案都谈到将SVG转换为画布,然后再将画布转换为PNG。而且答案也要老得多。我们可以不使用画布就能做到吗?
在我的项目中,我实际上没有html document
,只有一个.js
文件(据我所知,我们需要HTML5才能使用画布)。
我曾经使用Vercel来部署我的无服务器功能;
部署在:https://vercel-test-ruddy.vercel.app/api?yourName=YOUR_NAME_HERE
GitRepo:https://github.com/tharindusathis/vercel-test
答案 0 :(得分:1)
到目前为止,我发现的最好的处理方法是使用无头 chrome 并获取屏幕截图。作为使用 puppeteer
的示例,我可以获得如下所示的视口屏幕截图,
const browser = await puppeteer.launch();
const page = await browser.newPage();
let yourName = 'world'
const svg = `
<svg fill="none" viewBox="0 0 600 400" width="600" height="400" xmlns="http://www.w3.org/2000/svg">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">
<style>
.title {
font-size: 10vh;
font-weight: regular;
background-color: #ffddff;
}
</style>
<p class="title">Hello ${yourName}</p>
</div>
</foreignObject>
</svg>
`;
await page.setViewport({ width: 2048, height: 1170 });
await page.setContent(svg);
console.log(await page.content());
await page.screenshot({path: 'screenshot.png'});
await browser.close();
然后很容易发送 png
作为响应。
答案 1 :(得分:0)
就像您在解构查询参数一样,在这种情况下,它会在查询中搜索特定的对象属性。
如果您明确地将yourName用作查询参数,它应该可以工作。
https://vercel-test-ruddy.vercel.app/api?yourName=world
或不要解耦req.query对象属性。
<iframe src="https://vercel-test-ruddy.vercel.app/api?yourName=world" width="450px" height="450px">