3

I have a canvas which shows a graph and I'm trying to take a screenshot of the canvas using html2canvas() with the code below :

<div class="chartContainer" id="chart1"></div>
<div id="displayCanvas" style="display:none;" class="stx-dialog"></div>

html2canvas($('#chart1'),{onrendered:function(canvas1) 
{$('#displayCanvas').append(canvas1)}});

Here when the chart container is loaded the it uses the div with the id "displayCanvas" and appends the screenshot of the canvas.

How can I download the screenshot of the canvas which is displayed? I have already tried using something like below to download the image:

var link = document.createElement('a');
link.download = stx.chart.symbol+".png";
link.href = stx.chart.canvas.toDataURL("png");
link.click();

but it only downloads the data on the canvas as an image without the background (it does not download the screenshot but only the data) which when opened after downloading shows a black screen with data in it. Can anyone help me on how to download the image directly of the screenshot taken from the html2Canvas()?

Phoenix
  • 33
  • 1
  • 1
  • 5

4 Answers4

13

TRY THIS:

In the HTML:

  1. Give the element that you want to screenshot, an ID of "capture".
  2. Give the button/element that you would need to click to take the screenshot, an ID of "btn".
  3. Load the html2canvas.min.js file.

In the Javascript:

  1. Create the capture() function.
  2. Bind the capture() function to whatever event you are using—in this case it's on the btn click event.
  3. DONE! Watch the magic happen when you click on the btn.

HTML:

<h1 id="capture">Hellooooo</h1>
<button id="btn">Capture</button>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>

Javascript:

function capture() {
    const captureElement = document.querySelector('#capture') // Select the element you want to capture. Select the <body> element to capture full page.
    html2canvas(captureElement)
        .then(canvas => {
            canvas.style.display = 'none'
            document.body.appendChild(canvas)
            return canvas
        })
        .then(canvas => {
            const image = canvas.toDataURL('image/png')
            const a = document.createElement('a')
            a.setAttribute('download', 'my-image.png')
            a.setAttribute('href', image)
            a.click()
            canvas.remove()
        })
}

const btn = document.querySelector('#btn')
btn.addEventListener('click', capture)

Here's the JSFiddle

QUICK TIP: If you want to capture the whole document/webpage, then just add the "capture" ID to the <body> tag.

Ludolfyn
  • 1,806
  • 14
  • 20
  • This doesn't automatically download it though. You are adding a button. This is useless for local jobs with many images. You would then need to have a script click the button, which is a workaround I guess. – ThickMiddleManager Aug 14 '21 at 17:15
  • @ThickMiddleManager this _does_ automatically download the screenshot. The button is just a way to bind the function to some event for presentation's sake. It's the function that auto downloads the screenshot. You can bind the function to any event, e.g. a page load or in this case, a button click, and then it would still download the screenshot automatically. It works for any amount of elements and/or images. If you want to download screenshots of multiple elements consecutively, you could run the function on a loop. And it works in any local dev environment. I've tested it, it works. – Ludolfyn Aug 15 '21 at 12:55
  • @Ludolfyn i tried that code but i get got some issue : i am not getting whole html page image, capture some area which is showing currently. – userSLK Dec 06 '22 at 11:51
  • Hey @userSLK you can just change the `document.querySelector('#capture')` to `document.querySelector('body')`. And then it should capture the whole page. With that part you can select whichever part you want to capture. See JSFiddle example here: https://jsfiddle.net/Ludolfyn/dzvb4q7y/47/ – Ludolfyn Dec 06 '22 at 21:57
0

If there is black background at image your chart must be visible on screen. Because html2canvas like a taking screenshot. If you want converting data to canvas, you must be sure data is appear in screen.

İsa Baş
  • 106
  • 6
  • There is no background for the image, only the data is downloaded when I use canvas.toDataURL("png"). If i open the saved png in paint, it shows the image with the white background, else if I directly open the image using a viewer it show only the image with a black background. which makes it harder to read the data. – Phoenix May 15 '18 at 14:33
0

In case someone is using React, here is some code you can copy:

async function download() {
    const canvas = await html2canvas(document.querySelector("#screenshot"));
    canvas.style.display = "none";
    document.body.appendChild(canvas);
    const image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
    const a = document.createElement("a");
    a.setAttribute("download", `info.png`);
    a.setAttribute("href", image);
    a.click();
}

<a href="#" onClick={() => download()}>Download</a>
ospider
  • 9,334
  • 3
  • 46
  • 46
0

This worked for me:

HTML

<div id="canvasDiv">
    <canvas id="canvas" height="100" width="100">
        Your browser does not support the HTML canvas tag.
    </canvas>
 </div>
<button onclick="screenShot()" type="button">Take a screenshot</button>

Javascript

function screenShot(){
    html2canvas(document.querySelector("#canvasDiv")).then(canvas => {
        var dataURL = canvas.toDataURL( "image/png" );
        var data = atob( dataURL.substring( "data:image/png;base64,".length ) ),
            asArray = new Uint8Array(data.length);

        for( var i = 0, len = data.length; i < len; ++i ) {
            asArray[i] = data.charCodeAt(i);    
        }

        var blob = new Blob( [ asArray.buffer ], {type: "image/png"} );
        saveAs(blob, "photo.png");
    });
}

I just used the code provided in html2canvas site, then i used this code to download the screenshot.