Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take a screenshot of a webpage using html5, without rendering it on a canvas via JS

The important part is to take the screenshot

  • exactly as the user sees the browser window. This rules out canvas-based questions and answers, which emulate the browser but cannot exactly replicate how it renders html and css
  • without any non-standard plugins outside of plain, standards-compliant html5 and JS. This rules out Java applets, Flash, ActiveX, and kindly asking the user to press the "print-screen" button to then paste the image into a form.

I came across several questions on stackoverflow addressing this (see above), but did not find any answer that fulfilled both conditions. Instead of trying to add a partial answer for existing questions with slightly different requirements, I am asking this in a separate question instead.

I have so-far found a great explanation on how to acquire and stream pixels from a any window into a video element, using the Screen Capture API. However, I am missing the next step, where those pixels that are being displayed in a video element are converted into a jpg or png file that can be uploaded to a server.

like image 200
tucuxi Avatar asked Apr 02 '19 11:04

tucuxi


People also ask

How do I take a screenshot of a HTML page?

Please click on the toolbar button (or press Alt+Shift+D combination) to capture the screenshot. You can adjust the screenshot image format from the options page.

How do I take a screenshot of a website only?

Also, you can press Ctrl+Shift+P on Windows or Command+Shift+P on Mac. Type screenshot into the search box. Select Capture full-size screenshot. Once Chrome takes the screenshot, it should save it into your Downloads folder.

Can I take a screenshot with JavaScript?

A screenshot of any element in JavaScript can be taken using the html2canvas library. This library can be downloaded from its official website.


1 Answers

This is simpler than it seemed. The missing part, saving a still shot of the video to png, can be achieved with code from this answer. The complete code would be as follows:

const v = document.getElementById("v");
const b = document.getElementById("b");
const i = document.getElementById("i");

navigator.mediaDevices.getDisplayMedia({
  audio: false
}).then((r) => {
  console.log(r);
  v.srcObject = r;
}).catch((e) => {
  console.log("this must be run in a secure context. Stack snippets (rightfully) refuse to run this.");
});

b.onclick = () => {
  // take screenshot
  // from https://stackoverflow.com/a/44325898/15472
  let scale = 1;

  const canvas = document.createElement("canvas");
  canvas.width = v.clientWidth * scale;
  canvas.height = v.clientHeight * scale;
  canvas.getContext('2d').drawImage(v, 0, 0,
    canvas.width, canvas.height);

  i.src = canvas.toDataURL();
  // you can send i.src here to a server

  // stop video
  let tracks = v.srcObject.getTracks();
  tracks.forEach(track => track.stop());
  v.srcObject = null;
}
#v,
#i {
  width: 400;
  height: 300;
}

#v {
  border: 1px solid blue;
}

#i {
  border: 1px solid green;
}
<div>
  <video id="v" autoplay></video>
  <button id="b">take screenshot</button>
  <img id="i" src="//:0" />
</div>

Note that StackOverflow does not allow asking for screen-grabbing permissions, and therefore this code does not run here.

like image 61
tucuxi Avatar answered Oct 07 '22 18:10

tucuxi