admin管理员组文章数量:1287894
I am writing an nodejs script which will generate some info-graphic images using HTML.
I have used jsdom
library to generate the graphics with basic html elements (divs, headings, paragraphs, etc.).
const jsdom = require('jsdom');
const { document } = (new jsdom.JSDOM()).window;
const wrapper = document.createElement("div");
wrapper.style.cssText = "background:#eee;";
...
const el = document.createElement("div");
el.style.cssText = "background:red;";
el.innerText = "Sample Text";
...
wrapper.appendChild(el);
I can save this generated html (wrapper
) to a file. The saved file looks as expected. So the HTML generation part works fine.
But my requirement is to generate an image file (png, jpg, svg, or anything similar) with this generated html view.
I have tried, dom-to-image
and html-to-image
both failing saying "HTMLCanvasElement is not defined". I understand that since there is no browser in nodejs runtime, there are limitations such as these.
Is there a way to somehow generate an image from these generated HTML?
NOTE: This script will be running on a CICD pipeline on a linux server.
I am writing an nodejs script which will generate some info-graphic images using HTML.
I have used jsdom
library to generate the graphics with basic html elements (divs, headings, paragraphs, etc.).
const jsdom = require('jsdom');
const { document } = (new jsdom.JSDOM()).window;
const wrapper = document.createElement("div");
wrapper.style.cssText = "background:#eee;";
...
const el = document.createElement("div");
el.style.cssText = "background:red;";
el.innerText = "Sample Text";
...
wrapper.appendChild(el);
I can save this generated html (wrapper
) to a file. The saved file looks as expected. So the HTML generation part works fine.
But my requirement is to generate an image file (png, jpg, svg, or anything similar) with this generated html view.
I have tried, dom-to-image
and html-to-image
both failing saying "HTMLCanvasElement is not defined". I understand that since there is no browser in nodejs runtime, there are limitations such as these.
Is there a way to somehow generate an image from these generated HTML?
NOTE: This script will be running on a CICD pipeline on a linux server.
Share Improve this question asked Jan 8, 2020 at 23:40 charith.arumapperumacharith.arumapperuma 7041 gold badge7 silver badges22 bronze badges 1- 1 I'm late to the party but you could try puppeteer (headless chrome), I've never used it but seen good results in a specific app I collaborated in for a while. github./puppeteer/puppeteer – Rodrigo Commented Jan 9, 2020 at 1:01
1 Answer
Reset to default 10A little bit of a self-plug here but I just recently did the same thing with a project called kb-hologram.
It basically takes handlebar templates (either SVG or HTML), and renders that to either an SVG or png.
Basically, after having a ready HTML file, I load the HTML into a puppeteer instance (which actually runs a headless chrome browser), take a snapshot of the rendered HTML, and saves it.
it can generate things like a test report image (obviously fake numbers), or a changelog image similar to what vscode publishes in their tweets:
HTML
Here's the gist of it:
// handles rendering the HTML templates
// https://github./puppeteer/puppeteer
import puppeteer from 'puppeteer';
import { writeFile } from 'fs-extra';
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({
height: this.options.height,
width: this.options.width
});
// If your HTML is saved to a file, you load it like this:
await page.goto('file://' + this.templateFilePath);
// if your HTML is in memory (as a string), you load it like this:
// page.setContent(htmlString);
const imageBuffer = await page.screenshot({});
await browser.close();
// write file to disk as buffer
await writeFile('rendered.png', imageBuffer);
// convert to base64 string if you want to:
console.log(imageBuffer.toString('base64'));
})();
SVG
Generating an SVG is much simpler since it's basically a text file:
import { pile } from 'handlebars';
(async (data) => {
// generate the svg template as string
const template = await this.getTemplateAsString();
// make it a handlebars template
const handlebarsTemplate = pile(template);
// load the data into the template
// this is basically the content of the SVG file
const svgString = handlebarsTemplate(data);
// from here on, it's basically the same thing :-)
const svgBuffer = Buffer.from(svgString, 'utf8');
})(data);
Headless browser
To me, handling things like external resources is easier on a real browser if you want to load fonts and styles from CDNs. There are solutions out there to take a screenshot from jsdom directly if you don't want to introduce another "browser" module into the mix. Also, take note that this will download an instance of chrome as a dependency
kb-hologram
The project is still in early stages. Feel free to contribute to kb-hologram, fork the code, or write your own using the example. I personally use it on Travis CI
to publish tweets and images as PR ments on GitHub.
本文标签: javascriptHow to generate an image from dynamically created HTML in NodejsStack Overflow
版权声明:本文标题:javascript - How to generate an image from dynamically created HTML in Nodejs? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741323110a2372321.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论