Giter Club home page Giter Club logo

node-html-to-image's Introduction

Welcome to node-html-to-image ๐ŸŒ„

Version Documentation License: Apache--2.0 Twitter: yvonnickfrin

A Node.js library that generates images from HTML

๐Ÿ  Homepage

Description

This module exposes a function that generates images (png, jpeg) from HTML. It uses puppeteer in headless mode to achieve it. Additionally, it embarks Handlebars to provide a way to add logic in your HTML.

Install

npm install node-html-to-image
# or
yarn add node-html-to-image

Note: When you install Puppeteer, it downloads a recent version of Chromium (~170MB Mac, ~282MB Linux, ~280MB Win) that is guaranteed to work with the API.

Usage

Simple example

const nodeHtmlToImage = require('node-html-to-image')

nodeHtmlToImage({
  output: './image.png',
  html: '<html><body>Hello world!</body></html>'
})
  .then(() => console.log('The image was created successfully!'))

TypeScript support

The library is written in Typescript so it is available out of the box:

import nodeHtmlToImage from 'node-html-to-image'

Options

List of all available options:

option description type required
output The ouput path for generated image string optional
html The html used to generate image content string required
type The type of the generated image jpeg or png (default: png) optional
quality The quality of the generated image (only applicable to jpg) number (default: 80) optional
content If provided html property is considered an handlebars template and use content value to fill it object or Array optional
waitUntil Define when to consider markup succeded. Learn more. string or Array (default: networkidle0) optional
puppeteer The puppeteer property let you use a different puppeteer library (like puppeteer-core or puppeteer-extra). object (default: puppeteer) optional
puppeteerArgs The puppeteerArgs property let you pass down custom configuration to puppeteer. Learn more. object optional
beforeScreenshot An async function that will execute just before screenshot is taken. Gives access to puppeteer page element. Function optional
transparent The transparent property lets you generate images with transparent background (for png type). boolean optional
encoding The encoding property of the image. Options are binary (default) or base64. string optional
selector The selector property lets you target a specific element to perform the screenshot on. (default body) string optional
handlebarsHelpers The handlebarsHelpers property lets add custom logic to the templates using Handlebars sub-expressions. Learn more. object optional
timeout Timeout for a puppeteer-cluster (in ms). Defaults to 30000 (30 seconds). number optional

Setting output image resolution

node-html-to-image takes a screenshot of the body tag's content. If you want to set output image's resolution you need to set its dimension using CSS like in the following example.

const nodeHtmlToImage = require('node-html-to-image')

nodeHtmlToImage({
  output: './image.png',
  html: `<html>
    <head>
      <style>
        body {
          width: 2480px;
          height: 3508px;
        }
      </style>
    </head>
    <body>Hello world!</body>
  </html>
  `
})
  .then(() => console.log('The image was created successfully!'))

Example with Handlebars

Handlerbars is a templating language. It generates HTML from a template and an input object. In the following example we provide a template to node-html-to-image and a content object to fill the template.

const nodeHtmlToImage = require('node-html-to-image')

nodeHtmlToImage({
  output: './image.png',
  html: '<html><body>Hello {{name}}!</body></html>',
  content: { name: 'you' }
})
  .then(() => console.log('The image was created successfully!'))

Handlebars provides a lot of expressions to handle common use cases like conditions or loops.

Using Handlebars helpers

Handlerbars sub-expressions can be used to add custom logic to the templates. To do this, you must pass a handlebarsHelpers object with functions defined within.

For example, if you had a variable and wanted to do some conditional rendering depending on its value, you could do this:

const nodeHtmlToImage = require('node-html-to-image')

nodeHtmlToImage({
  output: './image.png',
  content: { myVar: 'foo' },
  handlebarsHelpers: {
    equals: (a, b) => a === b,
  },
  html: `
    <html>
      <body>
        {{#if (equals myVar 'foo')}}<div>Foo</div>{{/if}}
        {{#if (equals myVar 'bar')}}<div>Bar</div>{{/if}}
      </body>
    </html>`
  
})

Dealing with images

If you want to display an image which is stored remotely do it as usual. In case your image is stored locally I recommend having your image in base64. Then you need to pass it to the template with the content property. Here is an example:

const nodeHtmlToImage = require('node-html-to-image')
const fs = require('fs');

const image = fs.readFileSync('./image.jpg');
const base64Image = new Buffer.from(image).toString('base64');
const dataURI = 'data:image/jpeg;base64,' + base64Image

nodeHtmlToImage({
  output: './image.png',
  html: '<html><body><img src="{{{imageSource}}}" /></body></html>',
  content: { imageSource: dataURI }
})

Dealing with fonts

If you want to apply fonts, you need to synchronize your parts loading of your website. One way doing it is to convert your font to base64 and add it to your style in your html. For example:

const font2base64 = require('node-font2base64')

const _data = font2base64.encodeToDataUrlSync('../my/awesome/font.ttf')

const html = `
<html>
  <head>
    <style>
      @font-face {
        font-family: 'testFont';
        src: url("{{{_data}}}") format('woff2'); // don't forget the format!
      }
    </style>
  </head>
...

Using the buffer instead of saving to disk

If you don't want to save the image to disk and would rather do something with it immediately, you can use the returned value instead! The example below shows how you can generate an image and send it back to a client via using express.

const express = require('express');
const router = express.Router();
const nodeHtmlToImage = require('node-html-to-image');

router.get(`/api/tweet/render`, async function(req, res) {
  const image = await nodeHtmlToImage({
    html: '<html><body><div>Check out what I just did! #cool</div></body></html>'
  });
  res.writeHead(200, { 'Content-Type': 'image/png' });
  res.end(image, 'binary');
});

Generating multiple images

If you want to generate multiple images in one call you must provide an array to the content property.

Saving to disk

To save on the disk you must provide the output property on each object in the content property.

nodeHtmlToImage({
  html: '<html><body>Hello {{name}}!</body></html>',
  content: [{ name: 'Pierre', output: './image1.png' }, { name: 'Paul', output: './image2.png' }, { name: 'Jacques', output: './image3.png' }]
})
  .then(() => console.log('The images were created successfully!'))

Using buffers

If you don't want to save the images to disk you can use the returned value instead. It returns an array of Buffer objects.

const images = await nodeHtmlToImage({
  html: '<html><body>Hello {{name}}!</body></html>',
  content: [{ name: 'Pierre' }, { name: 'Paul' }, { name: 'Jacques' }]
})

Using different puppeteer libraries

If you want to use different puppeteer library you must provide the puppeteer property.

const chrome = require('chrome-aws-lambda');
const nodeHtmlToImage = require('node-html-to-image')
const puppeteerCore = require('puppeteer-core');

const image = await nodeHtmlToImage({
  html: '<html><body><div>Hello</div></body></html>',
  puppeteer: puppeteerCore,
  puppeteerArgs: {
      args: chromium.args,
      executablePath: await chrome.executablePath,
  }
})

Related

Libraries

Articles

Run tests

yarn test

Author

๐Ÿ‘ค FRIN Yvonnick [email protected]

๐Ÿค Contributing

Contributions, issues and feature requests are welcome!
Feel free to check issues page.

Show your support

Give a โญ๏ธ if this project helped you!

๐Ÿ“ License

Copyright ยฉ 2019 FRIN Yvonnick [email protected].
This project is Apache--2.0 licensed.


This README was generated with โค๏ธ by readme-md-generator

node-html-to-image's People

Contributors

adasq avatar busybox11 avatar cuire avatar cyberjag avatar dependabot[bot] avatar emhagman avatar favna avatar fcolacilli avatar frinyvonnick avatar gravelcycles avatar heziode avatar jewkesy avatar markdeuerling avatar michaeljgw avatar mrbjjackson avatar ozgurhalilince avatar robinmetral avatar sw7190 avatar tavyandy97 avatar tiffceet avatar y-temp4 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-html-to-image's Issues

Output image won't display images.

If I have an image in my html template, it is not displayed in the outputted image.

Is this something I am missing or does this not work?

<! DOCTYPE html> Error

Hello, it's funny, this error, luckily I fixed it but it would be nice to see what happens.

I am using " pug ":" ^ 3.0.0 " to create an HTML template parsed to string, apart from that I use " pdf-puppeteer ":" ^ 1.1.10 ", all good so far, it is generated the pdf.
Now go into action " node-html-to-image ":" ^ 2.1.1 ", I passed the same template but error
Node has 0 height.

The problem is not critical, but it is complex to find and it is only for this reason:
<! DOCTYPE html>
image

If the template contains exactly that, it breaks, my solution is no big deal, just delete that part

image

And now if, with that, both the pdf and the image are solved and are created.

With this another problem was born that I will leave in the issue #37

Ubuntu 18.04.5 LTS

Hi!
I am trying to install it on Ubuntu 18.04.5 LTS (GNU/Linux 5.3.0-1034-aws x86_64) and i received some dependencies errors from puppeteer. After installing the dependencies i received this error:
ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported

I solved this issue by adding the "--no-sandbox" argument:
nodeHtmlToImage({ html, puppeteerArgs: { args: ['--no-sandbox'] } })

Is there any other solution?

UnhandledPromiseRejectionWarning: Error: Browser is not downloaded. Run "npm install" or "yarn install"

I have installed this library in node js. I am trying to get an image from html but I get
UnhandledPromiseRejectionWarning: Error: Browser is not downloaded. Run "npm install" or "yarn install"
error always.
OS: Ubuntu 18.04 LTS
Node: v12.14.1
NPM: 6.14.5

Here is log:

(node:31583) UnhandledPromiseRejectionWarning: Error: Browser is not downloaded. Run "npm install" or "yarn install"
at ChromeLauncher.launch (webpack:///./node_modules/puppeteer/lib/Launcher.js?:236:15)
at module.exports (webpack:///./node_modules/node-html-to-image/src/index.js?:22:19)
at eval (webpack:///./app/helpers/HtmlToImage.js?:12:19)
(node:31583) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:31583) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Buffer() is deprecated

(node:3520) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.

Changing body size with background corrupts the end result

I'm trying to build a postcard image (png) using HTML, the body size is 320x512 and the background is the same. If you open this on chrome with device size (320x5120 it works perfectly.

See below :
Alt desc

But when I use node-html-to-image to convert the same HTML, the image goes to Right, and the postcard is corrupted. See: Alt desc

Here is the HTML to reproduce.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
        integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <title>Post Card</title>
</head>
<style>
    body {
          width: 320px;
          height: 512px;
    }
</style>
<style>
    .row {
        margin-right: 0;
    }
    .background {
        background-image: url(https://yeebaa-uploads-staging.s3.eu-west-1.amazonaws.com/templates/backgrounds/97089/419a5/093e9/4f8e7/5144c/1492f/bdc27/ac952/5745b/91ba7/60f69/019b9/d588.png);
        background-position: inherit;
        background-repeat: no-repeat;
        background-size: 320px 512px;
        height: 512px;
        width: 320px;
    }

    .input,
    .input {
        position: absolute;
        background-color: rgb(0, 0, 0, 0);
        border: none;
        border-bottom: 1px solid white;
        width: 220px;
        color: #000000;
        text-align: center;
    }

    
    .to-input {
        left: 50px;
        top: 30px;
        font-size: 20px;
    }
    
    .from-input {
        left: 50px;
        top: 420px;
        font-size: 20px;
    }
</style>
<body>
    <div class="row">
        <div class="col-lg-4 col-md-4 col-1"></div>
        <div class="col-lg-4 col-md-4 col-11">
            <div class="background">
                <form>
                                <input class="input to-input" name="to" id="to" type="text" value="osama">
                                <input class="input from-input" name="from" id="from" type="text" value="nisreen">
                </form>
            </div>
        </div>
        <div class="col-lg-4 col-md-4"></div>
    </div>
</body>

</html>

Expose screenshot args?

This package hides a lot of the screenshot arguments available in puppeteer. Can they be exposed?

`
page.screenshot([options])

options Options object which might have the following properties:
path The file path to save the image to. The screenshot type will be inferred from file extension. If path is a relative path, then it is resolved relative to current working directory. If no path is provided, the image won't be saved to the disk.
type Specify screenshot type, can be either jpeg or png. Defaults to 'png'.
quality The quality of the image, between 0-100. Not applicable to png images.
fullPage When true, takes a screenshot of the full scrollable page. Defaults to false.
clip An object which specifies clipping region of the page. Should have the following fields:
x x-coordinate of top-left corner of clip area
y y-coordinate of top-left corner of clip area
width width of clipping area
height height of clipping area
omitBackground Hides default white background and allows capturing screenshots with transparency. Defaults to false.
encoding The encoding of the image, can be either base64 or binary. Defaults to binary.
returns: <Promise<string|Buffer>> Promise which resolves to buffer or a base64 string (depending on the value of encoding) with captured screenshot.
`

How to set width and height value.

Hello,

First of all. You're a legend. This works 100%. There is still one question I have in mind.
How to set a width/height value to the image. I can't get it.

Hope to hear soon.

Generation of Images takes a really long time.

I am trying to generate an image from html, but it takes around 10 seconds to generate one image. I only have a single table in the html. Is there any way to reduce the image generation time?

Error: Unable to launch browser, error message: Failed to launch the browser process!

Whenever I use this package to display an image, it shows an error: Error: Unable to launch browser, error message: Failed to launch the browser process!
Here is my code:

const image = await nodeImage({
    html: '<html><body><div style="width: 300px; height: 200px; background-color: red;color: white">Check out what I just did! #cool</div></body></html>'
  });
  const attachment = new MessageAttachment(image);
  msg.channel.send(attachment);

Any ideas what's the problem?

Argument of type '{ output: string; html: string; }' is not assignable to parameter of type '{ html: any; output: any; type: any; content: any; quality: any; waitUntil?: string; transparent?: boolean; puppeteerArgs?: {}; encoding: any; }'.

I just copy pasted from README.md how to get started and this error welcomed me....

Argument of type '{ output: string; html: string; }' is not assignable to parameter of type '{ html: any; output: any; type: any; content: any; quality: any; waitUntil?: string; transparent?: boolean; puppeteerArgs?: {}; encoding: any; }'.

Not showing emoji

Hey everyone!
I'm trying to create an image with emojis on my Ubuntu server.

return await nodeHtmlToImage({ output: ./public/output, html: htmlFile, puppeteerArgs: { args: ["--no-sandbox"] } }).then(() => { return { image_src: output } }) .catch((err) => { console.log('nodeHtmlToImage Error: ', err) return err })

Result:
image

It's not showing the emoji. Why?

Thanks

Color issue

Hey im seeing a color mismatch. :/
im using bootstrap as a css lib
where the text should be the color white and the red and blue under the progress bar shouldnt be faded

im running on a aws ubuntu 20 instance

Current Image:
image

Previously Generated(goal):
imageDesired

const image = fs.readFileSync('./temp/images/backgrounds/bg.png');
const buffer = new Buffer(image);
const base64Image = buffer.toString('base64');
const dataURI = 'data:image/jpeg;base64,' + base64Image;

nodeHtmlToImage({
                output: `./temp/images/stats/image.png`,
                html: `<html lang="en"><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <style>html {-webkit-print-color-adjust: exact;} .margin-0{margin: 0px;}.margin-10{margin: 10px;}.margin-20{margin: 20px;}.margin-top-10{margin-top: 10px;}.margin-top-20{margin-top: 20px;}.margin-left-10{margin-left: 10px;}.margin-right-10{margin-right: 10px;}.margin-bottom-10{margin-bottom: 10px;}.margin-bottom-0{margin-bottom: 0px;}.padding-0{padding: 0px;}.padding-10{padding: 10px;}.padding-20{padding: 20px;}.padding-top-10{padding-top: 10px;}.padding-left-10{padding-left: 10px;}.padding-right-10{padding-right: 10px;}.padding-bottom-10{padding-bottom: 10px;}.padding-bottom-0{padding-bottom: 0px;}.grey-transparent-bg{background-color: rgba(0,0,0,.5);}.bottom-align{position: absolute; bottom: 0px;}.full-width{width: 100%;}.full-height{height: 100%;}</style></head><body style="width: 600px; height: 375px; background-color:transparent;"> <div class="container margin-top-10 border border-warning rounded" style="overflow: hidden;"> <div class="row" style="height: 15%;"> <div class="col-3 bg-dark d-flex align-items-center"> <h6 class="margin-bottom-0"> <span class="text-white">Lv.</span> <span class="badge badge-secondary margin-left-10 text-white">{{level}}</span></h6> </div><div class="col text-center bg-secondary d-flex align-items-center justify-content-center"> <h5 class="margin-bottom-0">{{username}}#{{discriminator}}</h5> </div><div class="col-2 bg-secondary d-flex align-items-center justify-content-center"> <img class="border border-dark rounded-circle bg-dark" src="{{userIcon}}" style="width:50px;height:50px;"/> </div></div><div class="row" style="height: 84.5%; background-image: url({{background}}); background-size: 100% 100%;"> <div class="col rounded padding-0 margin-20 grey-transparent-bg"> <div class="row"> <div class="col margin-10 text-white"> Level Status:{{levelCompletion}}% <span style="font-size: 10px; color: gray;">({{experience}}/{{levelExp}})</span> <div class="progress rounded-pill"> <div class="progress-bar bg-danger rounded-pill" role="progressbar" style="width:{{levelCompletion}}%"> </div></div><span class="margin-top-10 badge badge-danger">{{owner}}</span> <span class="margin-top-10 badge badge-primary">{{guildOwner}}</span> <span class="margin-top-10 badge badge-warning">{{supporter}}</span> </div></div><div class="row margin-top-20 text-white padding-left-10 padding-right-10" style="height: 70px;"> <div class="col text-center"> <div class="card bg-dark full-height"> <h6>Messages sent in{{guildName}}</h6> <span class="badge badge-secondary full-width bottom-align">{{messages}}</span> </div></div><div class="col text-center"> <div class="card bg-dark full-height"> <h6>Commands used in{{guildName}}</h6> <span class="badge badge-secondary full-width bottom-align">{{commands}}</span> </div></div><div class="col text-center"> <div class="card bg-dark full-height"> <h6>Mentions sent in{{guildName}}</h6> <span class="badge badge-secondary full-width bottom-align">{{mentions}}</span> </div></div></div><div class="row margin-top-10 text-white padding-left-10 padding-right-10" style="height: 70px;"> <div class="col text-center"> <div class="card bg-dark full-height"> <h6>Favorite command</h6> <span class="badge badge-secondary full-width bottom-align">{{command}}</span> </div></div><div class="col text-center"> <div class="card bg-dark full-height"> <h6>Number of fish caught</h6> <span class="badge badge-secondary full-width bottom-align">{{fishCaught}}</span> </div></div><div class="col text-center"> <div class="card bg-dark full-height"> <h6>Items held</h6> <span class="badge badge-secondary full-width bottom-align">{{itemsHeld}}</span> </div></div></div></div></div></div><script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script></body></html>`,
                content: {
                    level: 1,
                    username: 'SteeledSlagle13',
                    discriminator: '0113',
                    userIcon: '',
                    levelCompletion: (20 / 40) * 100,
                    experience: 20,
                    levelExp: 40,
                    owner: 'Owner',
                    guildOwner: 'Server Owner',
                    supporter: null, // TODO
                    guildName: 'STS',
                    messages: 0,
                    commands: 0,
                    mentions: 0,
                    command: null,
                    fishCaught: 0,
                    itemsHeld: 0,
                    background: dataURI
                },
                transparent: true,
                // waitUntil: 'networkidle0',
                // puppeteerArgs: '--force-color-profile=srgb|generic-rgb|color-spin-gamma24'
            }).then(() => {
                    console.log('Image created')
                });
            });

Using in AWS Lambda Function

I have enjoyed using the library so far. The one issue I have is that I can't deploy to a AWS Lambda function because the library (including Chromium I guess) pushes the size of the deployment package greater than 250MB. Any thoughts on how to make this deploy to AWS Lambda? I can use in a lambda function offline but can't be deployed due to package size.

Generating multiple images output issue

When I am trying to generate multiple image files by using array of values in content property as specified in the readme section below,
Generating multiple images
It gives 2 peculire issues -

  1. Sometimes the outputs are organised ( same as the content property value array ) but most of the time those aren't.
  2. Sometimes some images are skipped totally.

requirements?

it lib require chrome installed in the ssystem?

what rendering engine use it?

When deployed to heroku, "Unable to launch browser, error message: Failed to launch the browser process!" error occurs.

Unable to launch browser, error message: Failed to launch the browser process!
Found this in the logs:
/app/node_modules/puppeteer/.local-chromium/linux-737027/chrome-linux/chrome: error while loading shared libraries: libX11-xcb.so.1: cannot open shared object file: No such file or directory

I tried passing puppeteerArgs: { args: ["--no-sandbox", "--disable-setuid-sandbox"] } like

nodeHtmlToImage({
    html: "...",
    content: {...},
    puppeteerArgs: { args: ["--no-sandbox", "--disable-setuid-sandbox"] }
);

But it didn't work.

Error launching browser process on Raspberry Pi

Heya! I'm trying to use this module in a discord bot running on my raspberry pi (Raspbian 4.19.66-v7+, node v13.14.0) and I run into the following error when trying to use the module: https://pastie.io/vyzgce.txt

Here's the code I'm running, and it works as expected when run on my windows desktop. As you can see, I tried the fix from #18, ensured that all of the dependencies (and their dependencies) are installed, and also followed the instructions from here as suggested by the stack. Occasionally i will get a different error suggesting a re-runof npm install which I have done numerous times, which doesn't fix the problem.

Any ideas? Thanks in advance.

How to set window size?

How to set the size of the sceenshot? Already passed the --window-size=1920,1080 flag, but it still used the default resolution.

Batch multiple images

I would be nice to create multiple images using the same template in only one instance of puppeteer

Should Handlebars be a dependency?

Since not all users will necessarily use templating, and those that do can simply pass the output from Handlebars (or potentially some other HTML template library that might better suit their needs), should Handlebars really be a hard dependency for the package?

4 seconds to create the image

I have a simple html with Style and some divs but for some reason it takes almost 4 seconds to generate the image

const img = await nodeHtmlToImage({ output:'imagen4.png', quality:'1', html:
<style type="text/css">
li{
list-style:none
}
body{
width: 500px;height: 250px; border: solid 1px;
}
.head{
font-weight: bold;font-family:system-ui;font-size: 15px; text-align:center; border-bottom: solid 1px;

      }
      .baj{
        font-weight: bold;font-family:system-ui;font-size: 30px; text-align:center; border-bottom: solid 1px; border-top: solid 1px;
    
      }
      .fl{
        float: left;
        margin-right: 10px;
      }
      .image{
        text-align: center;
        margin-top: 20px;
        
      }
      .cajas{
          border-right: solid 1px;
          padding-right: 10px;
      }
      .ulformat{
        margin-top: 0px;
        margin-bottom: 0px;
        margin-left: -30px; 
        font-size: 12px;
      }
      </style>
      <body >
        <div class='head'><img src='https://Logoapp/img/2020/logo_negro.png' style='width: 95px;'></div>
        <div class="fl" >
          <ul class="ulformat">
          <li>
            Fecha	:
          </li>
            <li>
              Nombre	:
            </li>
            <li>
              Direccion:
            </li>
            
          </ul>
          
        </div>
        <div>
          <ul class="ulformat">
          <li>
              {{date_in}}
            </li>
            <li>
              {{name}}
            </li>
            <li>
              {{address}}
            </li>
           
          </ul>
        </div>
        <div>

        <div class="baj">
        N de orden: {{order_id}}
        </div>
      
      <div class='image'>
      <img style='text-align:center;' src='data:image/png;base64,{{barcode}}'>
      </div>


      </body>
    </html>
    `,
    content: { task_id: req.body.task_id, order_id: req.body.order_id, barcode: barra, address: req.body.address, name: req.body.name, date_in: req.body.date_in }
    });`

Please Help

Error: Failed to launch the browser process!

hi, i am writing a report. this is in repl.it, and i do have all dependencies, even the dependencies' dependencies installed. what do I do?
only use code snippet:

client.on('message', msg => {

  if (msg.content.startsWith('\`\`\`html') && msg.content.endsWith('\`\`\`')) {

    nodeHtmlToImage({

  	  output: 'image.png',

  	  html: msg.content.slice(7, msg.content.length - 3)

    })

	  .then(() => 

	    msg.channel.send(" ", {files: ["image.png"]})

	  )

  }

});

Conflict in case of instructions regarding output tag

`const express = require('express');
const router = express.Router();
const nodeHtmlToImage = require('node-html-to-image');

router.get(/api/tweet/render, async function(req, res) {
const image = await nodeHtmlToImage({
html: '

Check out what I just did! #cool
'
});
res.writeHead(200, { 'Content-Type': 'image/png' });
res.end(imgBinary, 'binary');
});`
Here in this sample, you have not given the output tag. But according to the code you mentioned that if there is no output tag it will throw error. Then you should make the use of output tag optional.

page.close() missing

I am using it in my project which I also use puppeteer.

The lack of "await page.close()" in "src/index.js" causes my script to fail when running "browser.newPage()".

Showing images or having background

Hi there, is there a way to display images using tag or using CSS? I can't seem to be able to display those when I render the images using this module

Error: You must provide an output property.

En la documentacion hay un ejemplo del estilo:
return await nodeHtmlToImage({
html: imageModelExample,
});

que en lugar de guardar la imagen en el proyecto devuelve el binario. Pero no funciona porque el parametro "output" es obligatorio.

Access to puppeteer page element

Is there any way to access the page element from puppeteer in node-html-to-image. For eg.

const bodyWidth = await page.evaluate(() => document.body.scrollWidth);
const bodyHeight = await page.evaluate(() => document.getElementById("wrapper").clientHeight);
await page.setViewport({ width: bodyWidth, height: bodyHeight, deviceScaleFactor: 2 });

If not can it be added? Maybe in the form of a function where we can access the page element, just before taking a screenshot.

Issue in using a custom ttf font within an express app

Hi
The library is wonderful and works perfectly. I want to know if I can use a custom ttf font deployed as part of my express app.
Sample code that doesnt work.

app.get(/api/tweet/render, async function(req, res) {
const htmlString = `


<style>
body {
width: 1600px;
height: 2000px;
}

  @font-face {
    font-family: "LCSmith_TypeWriter";
    src: url("./static/fonts/LCSmith_TypeWriter.ttf");
  }
</style>
Some text goes here `; const image = await nodeHtmlToImage({ html: htmlString, }); res.writeHead(200, { 'Content-Type': 'image/png' }); res.end(image, 'binary'); });

Please let me know if I am doing something wrong.

Use of the the link tag in the html head

Hi,
I want to use

<link
  href="https://fonts.googleapis.com/css?family=Poppins:400,700,900"
   rel="stylesheet"
 />

in my project. But after adding this tag, if I use the font family in the content, none of the content appears in the final image.
Also unable to add local images in the img src. I have to follow this:

const image = fs.readFileSync('./image.jpg');
const base64Image = new Buffer.from(image).toString('base64');
const dataURI = 'data:image/jpeg;base64,' + base64Image
 
nodeHtmlToImage({
  output: './image.png',
  html: '<html><body><img src="{{imageSource}}" /></body></html>',
  content: { imageSource: dataURI }
})

Are these bugs/new features to be added to the library?

Fonts Not Loading

Hi,
I try to add a font, but the font won't render at all.
I've added the font in the header and use it as a font-family in my body.

`
<style>
@font-face {
font-family: testFont;
src: url(https://some/awesome/font.ttf);
}
</style>

`

I already tried to wait for it, but still no success.

options.quality is unsupported for the png screenshots

I think this line cause trouble when I try to get a png:

quality = 80, // only applicable for jpg

I got this error:

Error: options.quality is unsupported for the png screenshots
    at assert (/app/node_modules/puppeteer/lib/helper.js:283:11)
    at Page.screenshot (/app/node_modules/puppeteer/lib/Page.js:903:7)
    at Page. (/app/node_modules/puppeteer/lib/helper.js:112:23)
    at ElementHandle.screenshot (/app/node_modules/puppeteer/lib/JSHandle.js:449:40)
    at runMicrotasks ()
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async module.exports (/app/node_modules/node-html-to-image/src/index.js:26:18)
    at async Object.postToInstagram (/app/plugins/MyApp/services/MyApp.js:1043:20)
    at async Object.postToInsta (/app/api/cdn/controllers/cdn.js:148:5)
    at async /app/node_modules/strapi/lib/middlewares/router/utils/routerChecker.js:77:22
    at async module.exports (/app/api/cdn/config/policies/isAdmin.js:4:12)
    at async module.exports (/app/node_modules/strapi-plugin-users-permissions/config/policies/permissions.js:112:3)
    at async /app/node_modules/strapi-utils/lib/policy.js:52:5
    at async serve (/app/node_modules/koa-static/index.js:59:5)
    at async strapi.router.get.koaStatic.maxage (/app/node_modules/strapi/lib/middlewares/public/index.js:92:11)
    at async evalmachine.:70:11
  -- ASYNC --
    at ElementHandle. (/app/node_modules/puppeteer/lib/helper.js:111:15)
    at module.exports (/app/node_modules/node-html-to-image/src/index.js:26:32)
    at runMicrotasks ()
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async Object.postToInstagram (/app/plugins/MyApp/services/MyApp.js:1043:20)
    at async Object.postToInsta (/app/api/cdn/controllers/cdn.js:148:5)
    at async /app/node_modules/strapi/lib/middlewares/router/utils/routerChecker.js:77:22
    at async module.exports (/app/api/cdn/config/policies/isAdmin.js:4:12)
    at async module.exports (/app/node_modules/strapi-plugin-users-permissions/config/policies/permissions.js:112:3)
    at async /app/node_modules/strapi-utils/lib/policy.js:52:5
    at async serve (/app/node_modules/koa-static/index.js:59:5)
    at async strapi.router.get.koaStatic.maxage (/app/node_modules/strapi/lib/middlewares/public/index.js:92:11)
    at async evalmachine.:70:11

Is Gitmoji a necessary dependency?

Hi @frinyvonnick, awesome package you've got here! I'm really excited to use it in production code, however I have a project running on Node v8.10.0 and the only blocker for installing this package is that gitmoji-changelog requires Node 10 or greater

$ yarn add-node-html-to-image
yarn run v1.10.1
error Command "add-node-html-to-image" not found.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
$ yarn add node-html-to-image
yarn add v1.10.1
info No lockfile found.
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] ๐Ÿ”  Resolving packages...
warning node-html-to-image > gitmoji-changelog > immutadot > babel-runtime > [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
warning node-html-to-image > gitmoji-changelog > libnpm > npm-lifecycle > node-gyp > [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142
[2/4] ๐Ÿšš  Fetching packages...
error [email protected]: The engine "node" is incompatible with this module. Expected version ">=10". Got "8.10.0"
error Found incompatible module
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

Base64 image issue

Running into an issue trying to use a base64 local image.

I saw Buffer has a deprecation warning so im using the buffer readFileSync returns as my image.

Going off the example this is what I would think would work, but I get a transparent image and not the image i am passing in...

Not sure if it is an issue or a thing on my end...

Code

const nodeHtmlToImage = require('node-html-to-image')
const fs = require('fs');

const image = fs.readFileSync('./test-2.png', 'base64');

nodeHtmlToImage({
    output: './image.png',
    html: `
    <html>
        <body>
            <img src="{{imageSource}}" />
        </body>
    </html>
            `,
    content: {
        imageSource: image
    },
    transparent: true
})
.then(() => console.log('The image was created successfully!'))

Workspace Setup
image

Current Example from README

const nodeHtmlToImage = require('node-html-to-image')
const fs = require('fs');
 
const image = fs.readFileSync('./image.jpg');
const base64Image = new Buffer(bitmap).toString('base64');
 
nodeHtmlToImage({
  output: './image.png',
  html: '<html><body><img src="{{imageSource}}" /></body></html>',
  content: { imageSource: base64Image }
})

Current Output
image

Expected Output
image

Define height and width in html

Nothing has changed since issue #36 , the same libraries are still used, now the problem is that, if the image that is generated is cropped.

Both libraries receive the same template generated by pug (taking the consideration described in issue # 36 to generate the image)

PDF:
image

IMAGE:
image

In pdf-puppeteer it is solved in this way

image

But, what would be the way to do it in node-html-to-image?

Using the buffer not working

In the readme says that we can get the buffer using:

const image = await nodeHtmlToImage({
    html: "<html><body>HELLO</body></html>"
});

But that throws exception immediately:

(node:22148) UnhandledPromiseRejectionWarning: Error: You must provide an output property.
    at module.exports (C:\Workspace\Personal\html-calendar\node_modules\node-html-to-image\src\index.js:17:11)
    at getImageBuffer (C:\Workspace\Personal\html-calendar\html-image.js:17:18)
    at Object.<anonymous> (C:\Workspace\Personal\html-calendar\html-image.js:8:5)
    at Module._compile (internal/modules/cjs/loader.js:1151:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10)
    at Module.load (internal/modules/cjs/loader.js:1000:32)
    at Function.Module._load (internal/modules/cjs/loader.js:899:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47
(node:22148) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:22148) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Error: Unable to get browser page

Getting this error,

> node index.js

Listening on 5000
(node:4018) UnhandledPromiseRejectionWarning: Error: Unable to get browser page
    at Worker.<anonymous> (/Users/partharoy/Desktop/dev/b/bCard/node_modules/puppeteer-cluster/dist/Worker.js:44:31)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/partharoy/Desktop/dev/bengalbyte/bbCard/node_modules/puppeteer-cluster/dist/Worker.js:5:58)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:4018) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:4018) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Render an element in the body

Sometimes I just want to convert one element in the html file into a picture, instead of the body elements.Can this feature be implemented?Thanks!

error while loading shared libraries: libX11-xcb.so.1: cannot open shared object file: No such file or directory

Hi,
A project with NodeJS latest version with express.
In localhost is everything fine and working perfectly, but when I deploy on Heroku and try to run the function I get this error.

Failed to launch the browser process! /app/node_modules/node-html-to-image/node_modules/puppeteer/.local-chromium/linux-722234/chrome-linux/chrome: error while loading shared libraries: libX11-xcb.so.1: cannot open shared object file: No such file or directory

Its something chromium related, do you have any fix for this?

thanks

Can html file be used?

Hello bro, thanks for this module.
Can html file be used instead of an html string?

In example:

  nodeHtmlToImage({
    output: './image.png',
    html: './myhtmlfile.html'
  })

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.