39

I'm rendering a screenshot onclick with HTML2canvas .4.1 and want to save the image to user's local computer. How can this be accomplished? Please note that I'm a beginner, so actual code will be most helpful to me.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="html2canvas.js"></script>

<button id="save_image_locally">download img</button>

   <div id="imagesave">
      <img id='local_image' src='img1.jpg'>
   </div>

<script>

    $('#save_image_locally').click(function(){

            html2canvas($('#imagesave'), 
             {
                onrendered: function (canvas) {
                    var img = canvas.toDataURL("image/png");
                    alert('This will currently open image in a new window called "data:". Instead I want to save to users local computer. Ideally as a jpg instead of png.');
                    window.open(img);
                }
             });
            });

</script>
TheGrayVacuum
  • 703
  • 2
  • 7
  • 12

5 Answers5

65

NOTE: this answer is from 2015 and the library has been updated.
Check the answers below for alternate implementations.

Try this (Note that it makes use of the download attribute. See the caniuse support table for browsers that support the download attribute)

<script>

  $('#save_image_locally').click(function(){
    html2canvas($('#imagesave'), 
    {
      onrendered: function (canvas) {
        var a = document.createElement('a');
        // toDataURL defaults to png, so we need to request a jpeg, then convert for file download.
        a.href = canvas.toDataURL("image/jpeg").replace("image/jpeg", "image/octet-stream");
        a.download = 'somefilename.jpg';
        a.click();
      }
    });
  });

</script>
2pha
  • 9,798
  • 2
  • 29
  • 43
  • 1
    Oh, the toDataURL function also takes a second parameter for quality between 0 and 1 if you want to set the jpeg quality/filesize – 2pha Jul 27 '15 at 15:38
  • 1
    Thanks @2pha. This worked for me. Much appreciated. At first there was some extra space getting saved, beyond the border of the original image. I was able to fix by adding style to the div. For example, to save a 512x512 image I did this:
    – TheGrayVacuum Jul 27 '15 at 22:00
  • Thanks for this. However, when I apply this, everything works but the background is black instead of white. Any idea on how to fix this? – Arko Elsenaar Jun 08 '16 at 07:35
  • 1
    @ArkoElsenaar add css `background-color:white` to your element. or look at other solutions here: http://stackoverflow.com/questions/14584946/how-to-make-transparent-color-white-instead-of-black-in-canvas – Shoham Jul 12 '16 at 14:03
  • This is the perfect solution you can change the jpg to png `a.href = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");` – Ahmed Bermawy Apr 26 '17 at 14:35
  • png is actually the default, So `toDataURL()` would actually return the same as `toDataURL("image/png")`. I just put it there to demonstrate that you could request a type. To get a jpg, you would do `toDataURL("image/jpeg")` – 2pha May 03 '17 at 23:53
44

update 2018

Notice that in the new versions of Html2Canvas the onrendered option is deprecated and replaced with promises.

To be able to download the image to the user computer, you may use something like this:


Html

<html>
    <head></head>
    <body>
        <div id="boundary">
            <div class="content">
                <p>My content here</p>
            </div>
        </div>

        <button id="download">Download</button>
        
    </body>
</html>

Javascript

Based on Krzysztof answer

document.getElementById("download").addEventListener("click", function() {
    
    html2canvas(document.querySelector('#boundary')).then(function(canvas) {

        saveAs(canvas.toDataURL(), 'file-name.png');
    });
});


function saveAs(uri, filename) {

    var link = document.createElement('a');

    if (typeof link.download === 'string') {

        link.href = uri;
        link.download = filename;

        //Firefox requires the link to be in the body
        document.body.appendChild(link);

        //simulate click
        link.click();

        //remove the link when done
        document.body.removeChild(link);

    } else {

        window.open(uri);

    }
}

Issue encountered

Indeed i was able to download the image, but it was blank ...the possible cause for this (at least in my case) was that the content wrapper (id="#boundary") has no width or height defined, so specifying a height and a width to the content wrapper did the trick for me.


hope this helps

chebaby
  • 7,362
  • 50
  • 46
7

This is the latest code that convert to PNG.

      $("#btnSave2").click(function() {
        html2canvas($("#widget"), {
          onrendered: function(canvas) {
            saveAs(canvas.toDataURL(), 'canvas.png');
          }
        });
      });

      function saveAs(uri, filename) {
        var link = document.createElement('a');
        if (typeof link.download === 'string') {
          link.href = uri;
          link.download = filename;

          //Firefox requires the link to be in the body
          document.body.appendChild(link);

          //simulate click
          link.click();

          //remove the link when done
          document.body.removeChild(link);
        } else {
          window.open(uri);
        }
      }
Zhong Ri
  • 2,556
  • 1
  • 19
  • 23
6

2022 Answer:

<html>
  <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"></script>
  </head>
  <body>
  <div id="to_save" style="text-align: center; width:300px; height: 300px;"> 
What is Lorem Ipsum?

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</div>

  <button id="download"> Download </button>
    
  <script>
    $( "#download" ).on( "click", function() {
      html2canvas(document.querySelector("#to_save")).then(canvas => {
        canvas.toBlob(function(blob) {
          window.saveAs(blob, 'my_image.jpg');
        });
        });
    });
  </script>
 
  </body>
</html>

DEMO

SRC

Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268
0
function saveAs(blob, fileName="pic") {
    const link = document.createElement('a');
    link.download = fileName
    link.href = URL.createObjectURL(blob);
    link.click();
    URL.revokeObjectURL(link.href);
}

Html2Canvas(element).then(canvas => {
    canvas.toBlob((blob)=> {
      saveAs(blob, fileName)
    })
})

Liu Lei
  • 1,256
  • 1
  • 9
  • 18