Let’s say you want to save the screenshot of a webpage in Django. For example, you might need to store a screenshot of an agreement with your client’s signature when it’s filled up and submitted.

If you look for an external library to do this, you might stumble upon django-screamshot. I haven’t tried this library, but it looks promising.

In this tutorial, however, I’ll show you how to achieve this using the HTML5 Canvas and Python.

Here’s my implementation of a Django save screenshot feature:

html2canvas

This is a great tool that converts a webpage — or parts of it — into an image using the HTML Canvas. You can download it here. There’s also a CDN. Include it on your webpage with the following code, and you’re good to go.

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>

 

The Django Form

The form class for this needs to contain a CharField that will hold the data for the image. We use a CharField instead of something like an ImageField because we can’t programmatically populate a file upload field in HTML due to security reasons. So, we get the image in an encoded format and pass it along to the backend from the CharField. Here’s the form I used:

 

The HTML Page

This is the page we’ll be taking a screenshot of. For now let’s just include a bootstrap panel in there some dummy text. We also need a button to submit the form. Here’s the code:

This is what it looks like:

Webpage

The JavaScript code

Now we need to use html2canvas to generate an image of our website with some JavaScript. The examples shown on the official site only show how to generate and display the image, but we’ll need to convert the image to a data uri in order to send it to the backend. Here’s my implementation:

Decoding the Image

Now that we have the image data at the backend, we need to decode it into an actual image and save it where we need. This will require some base64 encoding and decoding magic that took wading through an incredible number of StackOverflow links to figure out. Here’s what I used in the end.

Final Result

Here’s the result of the Django save screenshot:

Django save screenshot

 

Notes:

  1. If you need a png image instead of a jpg, use canvas.toDataURL('image/png');
  2. For this simple webpage, the screenshot is quite perfect. However, if you have complex CSS on your page, some elements may not render correctly.