画布使用vega和nodejs时出现问题(仅限服务器端)



我已经在Discord机器人上工作了几个星期,这个机器人基本上在服务器上编译统计数据并推导模式。为了改进它,我想让它将图生成为PNG,以便将它们发送回用户——简而言之,没有DOM。为了实现这一点,我目前正在使用vega(版本5.10.1-最新(和node-cavas(版本2.6.1-最新(,以及nodejs v12.16.1。

我一直在网上搜索关于素食主义者使用的帮助,发现了一些相互矛盾的消息来源。我一直在使用这里提供的示例代码:https://vega.github.io/vega/usage/

问题是,我一直得到这个错误:

TypeError: Cannot read property 'getContext' of null
message:"Cannot read property 'getContext' of null"
stack:"TypeError: Cannot read property 'getContext' of null
at resize (e:DEVGIT REPOSGITHUBPERSOJStest-StatBotnode_modulesvega-scenegraphbuildvega-scenegraph.js:3665:28)
at CanvasRenderer.prototype$6.resize (e:DEVGIT REPOSGITHUBPERSOJStest-StatBotnode_modulesvega-scenegraphbuildvega-scenegraph.js:3714:5)
at CanvasRenderer.prototype$4.initialize (e:DEVGIT REPOSGITHUBPERSOJStest-StatBotnode_modulesvega-scenegraphbuildvega-scenegraph.js:3294:17)
at CanvasRenderer.prototype$6.initialize (e:DEVGIT REPOSGITHUBPERSOJStest-StatBotnode_modulesvega-scenegraphbuildvega-scenegraph.js:3709:28)
at initializeRenderer (e:DEVGIT REPOSGITHUBPERSOJStest-StatBotnode_modulesvega-viewbuildvega-view.js:657:8)
at renderHeadless (e:DEVGIT REPOSGITHUBPERSOJStest-StatBotnode_modulesvega-viewbuildvega-view.js:780:12)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async View.renderToCanvas [as toCanvas] (e:DEVGIT REPOSGITHUBP...

这是给我带来麻烦的代码:

// Imports
const vega = require('vega');

// Render image from given graph spec (statsObject)
async function graphToImage (statsObject) {
graphObject = new vega.View(vega.parse(statsObject), { renderer: 'none'});
const pngName = generateFileName(10);
removeExistingFile(pngName);
graphObject.toCanvas().then(canvas => {
console.log('Writing PNG to file...');
writeFile(`../../../../generated/${pngName}.png`, canvas.toBuffer());
}).catch(err => {
console.log("Error writing PNG to file:");
console.error(err);
});

return pngName;
}

我真的不知道canvas或vega是如何工作的,所以我不知道是什么导致了这个问题,也不知道如何解决它……然而,这个问题似乎位于toCanvas()方法内部。非常感谢您的帮助!

提前感谢!

// Using view.toSVG() along with the npm package sharp worked well for me 

const view = new vega.View(vega.parse(templateObject), {renderer: 'none'});
view.toSVG().then(async function (svg) {
await sharp(Buffer.from(svg))
.toFormat('png')
.toFile('fileName.png')
}).catch(function(err) {
console.error(err);
});

编辑:我设法解决了我的问题,我将在这里发布anwser以备将来通知:

通过使用view.toSVG()而不是有缺陷的view.toCanvas(),将View对象直接渲染为SVG字符串,我成功地生成了一个图形图片,效果非常好。

然后,剩下要做的就是将获得的SVG字符串转换为PNG文件,就这样了

这是更新的工作代码:

// Imports
const vega = require('vega');

// Render image from given graph object
async function graphToImage (statsObject) {
// Generate a new 10-char hex string
const pngName = generateHexStringName(10);

// Remove any existing file with the same name in order to prevent confusion
removeExistingFile(pngName);

var view = new vega.View(vega.parse(statsObject), {renderer: 'none'});

// Generate an SVG string
view.toSVG().then(async function (svg) {
// Working SVG string
console.log(svg);
// Process obtained SVG string, e. g. write it to PNG file

}).catch(function(err) {
console.error(err);
});

// Return the name of the generated PNG file
return pngName;
}

最新更新