Image from html

Hi everyone,

I need to generate an image with data from Home Assistant which will later be shown on an e-ink display.

I'd like to use the template node for that.

The generated html should then be converted into an image. The image-tools node unfortunately does not "read" the html but rather just takes the html as it is and prints html sourcecode. (The output of the template node is plain text)

I thought about generating the html and then screenshotting it but the screenshot nodes require an executable browser installed, which I don't have on Synology NAS.

Any idea how I can generate such an image while being able to design the layout a bit?

Thanks

Without a headless capable browser, you will need another command line tool to convert html to an image. Does your html require JavaScript? If so, then a headless browser is about the only possible option.

Once you can do it from the command line, the node-red part is trivial using the exec node.

Otherwise, you could probably use something like html-to-image - npm (npmjs.com).

There is also an nbrowser node which might do the trick - not used it so not sure. Oh yes, nbrowser has a save-as that allows image type.

Thanks, nbrowser looks awesome! I'll try that out today.

So I tried out nbrowser but unfortunately saveas is not working for me, as described by someone here: Nbrower node : Saveas doesn't work?
I also tried it with a non-docker installation but also there it is not working.

Would you have an idea on how to use html-to-image? I already worked with the function node and npm modules but always had to get a lot of support as - honstely - I pretty much have no idea how to convert the samples of such nodes to work in Node Red.

Thanks!

Node-RED now has two ways to work with external npm modules that aren't node-red nodes.

If you turn on the option in settings.js (sorry never can remember what it is called), you can use npm and modules right in your function nodes. As in this example:

In that case, in the On Message section where you put your main code, you can simply refer to the imported name - aaa in that case.

If you don't want to turn that on, also in settings.js is a globals section. There you can add a line like aaa: require('aaa'),. You would have to manually install the aaa module into your userDir (where the settings and flows live). Then in your function node, you would need to add at the start const aaa = global.get('aaa').

Generally after that, it is usually a case of following any instructions in the modules docs.

Hmm, though looking at html-to-image again, it looks like it wants a DOM element rather than text. I'm afraid that means that you also need a 2nd module dom-parser. That lets you use the DOM browser API in Node.js.

The following is completely off the top of my head and untried

// Assuming we've already got refs to dom-parser and html-to-image
const parser = new DomParser()
const dom = parser.parseFromString( msg.payload ) // assuming msg.payload holds the html string

htmlToImage.toPng( dom.outerHTML() )
  // dataUrl is a base64 encoded data URL, you might need to turn it back into an image
  // using a base64 converter - there is a node for that I think.
  .then(function (dataUrl) {
    download(dataUrl, 'my-node.png') // MAYBE! not sure about this.
  })
  .catch(function (error) {
    node.error('oops, something went wrong!', error)
  })

Sorry, I haven't got the time to actually try this myself right now but hopefully that might be enough pointers to get you started at least.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.