Set Width and Height of Element Screenshot in Puppeteer
Asked Answered
A

3

9

If I have this code:

const puppeteer = require('puppeteer');

var test = async () => {
  const browser = await puppeteer.launch({args: ["--no-sandbox", "--disable-setuid-sandbox"]});
  const page = await browser.newPage();
  await page.goto('https://community.wikia.com/wiki/Special:WikiActivity');
  let element =  await page.$('#WikiaMainContent');
  await page.setViewport({ width: 800, height: 1000}); // This is ignored
  await element.screenshot({path: "./wiki.png"});
  await browser.close(); 
}

test();

The screenshot is larger than the viewport.

How can I make it so that the screenshot has a width of 800px and height of 1000px?

Accentual answered 29/9, 2018 at 22:36 Comment(3)
Sorry, I wrote this code from memory, please check the edit.Accentual
In the corrected code, you do not call a main IIFE-function?Alignment
I've tested this one properly now. It generates a new image, but it is still too largeAccentual
E
31

You can use the clip option of elementHandle.screenshot() in conjunction with elementHandle.boundingBox() to set the width and height of an element screenshot.

The example below will take a screenshot of an element, and clip the element if it exceeds the current viewport:

await page.setViewport({
  width: 800,
  height: 1000,
});

const example = await page.$('#example');
const bounding_box = await example.boundingBox();

await example.screenshot({
  path: 'example.png',
  clip: {
    x: bounding_box.x,
    y: bounding_box.y,
    width: Math.min(bounding_box.width, page.viewport().width),
    height: Math.min(bounding_box.height, page.viewport().height),
  },
});
Exhaustive answered 30/9, 2018 at 23:48 Comment(0)
V
1

I have a better solution using html2canvas in the front:

https://gist.github.com/homam/3162383c8b22e7af691085e77cdbb414

or using it with puppeteer and html2canvas in the Backend:

const screenshot = await page.evaluate(async () => {
   const canvasElement = await html2canvas($("div")[0], {
        // useCORS: true,
   });

   let image = Canvas2Image.convertToImage(
        canvasElement,
        $(canvasElement).width(),
        $(canvasElement).height(),
        "png"
    );
    console.log(image.src)
    return image.src;
})
var fs = require('fs');
// strip off the data: url prefix to get just the base64-encoded bytes
var data = screenshot.replace(/^data:image\/\w+;base64,/, "");
var buf = new Buffer(data, 'base64');
fs.writeFile(`./screenshots/div-${Date.now()}-.png`, buf);

full code here: https://github.com/davidtorroija/screenshot-of-div-e2e/blob/master/README.md

this is better because is easy to take a screenshot of a huge div, and no need to scroll, and you are not going to lose any part of the div

Varro answered 30/5, 2019 at 17:58 Comment(0)
C
0

Lauching puppeteer with defaultViewport, worked for me:

await puppeteer.launch({ headless: 'new', defaultViewport: { width: 1920, height: 1080 } })
Calvo answered 14/6 at 21:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.