0

I have a HTML template file in node js. And I want to convert that template with into image by replacing static values with dynamic values. Suppose I have a below HTML template saved in any variable in my CONFIG file:

const puppeteer = require('puppeteer')
const htmlString = `<html>
                    <head>
                      <title></title>
                    </head>
                    <body>
                      <div class="container" style="height:500px;width:450px;border:1px solid silver;margin:0 auto">
                        <header style="height:200px;background-image: url('https://i.imgur.com/a1ItuWs.jpg');">
                            <center>
                              <span style="font-size:55px;color:white;font-weight: bold;font-family: arial;margin-top:20px">Hello</span>
                              <br>
                              <span style="font-size: 35px;color: white">rajat</span>
                              <br><br>
                              <span style="font-size:20px;color: white;font-family: arial;">from biondi Goh</span>
                            </center>
                        </header>
                        <section style="height: 280px;background: #ecfaff">
                          <center>
                            <span style="font-size: 30px;font-family: arial;">rajat subject</span>
                            <br><br>
                            <span style="font-size: 20px;font-family: arial;">rajat paragraph 1</span>
                            <br><br>
                            <span style="font-size: 20px;font-family: arial;color:red;">RAJAT INTEREST</span>
                            <br><br>
                            <span style="font-size: 20px;font-family: arial;">rajat Paragraph 2</span>
                          </center>
                        </section>
                        <footer style="height:20px;background: #ecfaff;text-align: center;font-family: arial;">
                            <span>http://biondi.assured.sg</span>
                        </footer>
                      </div>
                    </body>
                    </html>`;

(async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  await page.setContent(htmlString)
  await page.screenshot({path: 'example.png',type: "jpeg", quality: 100})
  await browser.close()
})()

I want to create above HTML image. Can anyone please suggest me library for this?

Rajat
  • 486
  • 1
  • 10
  • 35
  • I am not sure if you are asking for this, but it could work: https://stackoverflow.com/questions/45207479/a-similar-solution-to-html2canvas-with-nodejs – No One Jan 25 '19 at 10:40
  • @NoOne, No i am not using ejs. I just have html saved in variable and i want to create image from that. – Rajat Jan 25 '19 at 10:44
  • to use dynamic values in string literals you can use ${} and pass your value inside curly braces as \`static value ${dynamic value}`. Refer https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Syntax – AZ_ Jan 25 '19 at 10:53
  • @Ariz, I know this. Just gave the sample above. Please let me know the library for that. – Rajat Jan 25 '19 at 11:16

1 Answers1

5

You can render a HTML string to an image in node.js by using Puppeter

npm install -S puppeteer

const puppeteer = require('puppeteer')

const htmlString = `<html>
<head>
    <title></title>
</head>
<body>
    <div class="container" style="height:200px;width: 200px;border: 1px solid red">
        <header style="height:50px">
            Header
        </header>
        <footer style="height:100px">
            footer
        </footer>
    </div>
</body>
</html>`;

(async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  await page.setContent(htmlString)
  await page.screenshot({path: 'example.png'})
  await browser.close()
})()

This will create example.png in your folder, it's also possible to clip the image or remove the background by adding properties https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagescreenshotoptions

Daniel Doblado
  • 2,481
  • 1
  • 16
  • 24
  • Thanks for your answer. Can you please tell me, is this module works at node js side? – Rajat Jan 25 '19 at 11:51
  • Yes, you just need to do `npm install -S puppeteer` to make it work on node.js – Daniel Doblado Jan 25 '19 at 11:53
  • Can you please tell me one more thing? – Rajat Jan 25 '19 at 11:58
  • I will get form fields values from android app and have to create image by replacing static values in htmlTemplate with those form fields values and then return image to android app. So, Won't above code open a browser in android app while running that api? – Rajat Jan 25 '19 at 12:04
  • For that you would need a fully functional server, e.g. with [Express](https://expressjs.com/), which handles the incoming request with the form values and sends them to Puppeteer. – Thomas Brok Jan 25 '19 at 12:11
  • @DanielDoblado, I applied background image, but it is not coming. – Rajat Jan 25 '19 at 13:30
  • @Rajat can you update your code with the background image? – Daniel Doblado Jan 25 '19 at 13:33
  • @DanielDoblado, sure sir. Please give me 1 minute. – Rajat Jan 25 '19 at 13:36
  • @DanielDoblado, I have updated by question with the latest code, i am using. – Rajat Jan 25 '19 at 13:38
  • @DanielDoblado, Can you please help me regarding this? – Rajat Jan 25 '19 at 13:45
  • Like @ThomasBrok said you need an express server or something similar to serve the file, instead I would suggest you to upload the image to some service and call it like this `
    ` I tested this and works. `
    – Daniel Doblado Jan 25 '19 at 13:47
  • @DanielDoblado, I am using express server and my html is saved in my variable as you can see. – Rajat Jan 25 '19 at 13:51
  • @DanielDoblado, Yes it worked. Thanks a lot. You saved my day. – Rajat Jan 25 '19 at 13:54
  • @DanielDoblado, My image quality is low. It is showing blurry text. Can you please tell me, how can i fix that? – Rajat Jan 25 '19 at 13:56
  • @Rajat that happens either because the image itself is of low quality (which I don't suspect, since you mentioned it is now low, and not before), or the way your choice of content delivery network processes the image and sends it upon request. – Thomas Brok Jan 25 '19 at 14:02
  • No, Module is creating image in low quality from starting. – Rajat Jan 25 '19 at 14:04
  • try adding "await page.screenshot({path: 'example.jpeg', type: "jpeg", quality: 100})" jpeg and the quality – Daniel Doblado Jan 25 '19 at 14:04
  • @DanielDoblado, Tried, But same result. – Rajat Jan 25 '19 at 14:06
  • @DanielDoblado, It is creating png images instead of jpeg, as i give options written by you. Please have a look at the updated code. – Rajat Jan 25 '19 at 14:08
  • To increase the quality you can set size the viewport with this `await page.setViewport({"width": 1920, "height": 1080, "deviceScaleFactor" : 1.5 })` as mentiononed here https://github.com/GoogleChrome/puppeteer/issues/1329 – Daniel Doblado Jan 25 '19 at 14:14
  • @DanielDoblado, It is still blur. Can you please find a better solution for it. I don't want full hd image. But it should not be blurry. Thanks. – Rajat Jan 25 '19 at 14:32
  • You can increase `deviceScaleFactor` as much as you want here is a comparison between a value of `1.5` on the left and `2`(retina display) on the right as you can see the right one is more smooth. https://imgur.com/fzIFBMa But I don't have more ideas on how to help you on this issue. – Daniel Doblado Jan 25 '19 at 14:43
  • @DanielDoblado, Do you know any other library. – Rajat Jan 25 '19 at 18:19
  • @Rajat as an alternative you could use something like jsdom to create a dom node with your html and then convert the dom node to canvas that can be output as an image but is overly complex to explain here. – Daniel Doblado Jan 25 '19 at 18:52