How To Save Canvas As An Image With canvas.toDataURL()?

445,391

Solution 1

Here is some code. without any error.

var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");  // here is the most important part because if you dont replace you will get a DOM 18 exception.


window.location.href=image; // it will save locally

Solution 2

This solution allows you to change the name of the downloaded file:

HTML:

<a id="link"></a>

JAVASCRIPT:

  var link = document.getElementById('link');
  link.setAttribute('download', 'MintyPaper.png');
  link.setAttribute('href', canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"));
  link.click();

Solution 3

You can try this; create a dummy HTML anchor, and download the image from there like...

// Convert canvas to image
document.getElementById('btn-download').addEventListener("click", function(e) {
    var canvas = document.querySelector('#my-canvas');

    var dataURL = canvas.toDataURL("image/jpeg", 1.0);

    downloadImage(dataURL, 'my-canvas.jpeg');
});

// Save | Download image
function downloadImage(data, filename = 'untitled.jpeg') {
    var a = document.createElement('a');
    a.href = data;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
}

Solution 4

You can use canvas2image to prompt for download.

I had the same issue, here's a simple example that both adds the image to the page and forces the browser to download it:

<html>
    <head>
        <script src="http://hongru.github.io/proj/canvas2image/canvas2image.js"></script>
        <script>
            function draw(){
                var canvas = document.getElementById("thecanvas");
                var ctx = canvas.getContext("2d");
                ctx.fillStyle = "rgba(125, 46, 138, 0.5)";
                ctx.fillRect(25,25,100,100); 
                ctx.fillStyle = "rgba( 0, 146, 38, 0.5)";
                ctx.fillRect(58, 74, 125, 100);
            }

            function to_image(){
                var canvas = document.getElementById("thecanvas");
                document.getElementById("theimage").src = canvas.toDataURL();
                Canvas2Image.saveAsPNG(canvas);
            }
        </script>
    </head>
    <body onload="draw()">
        <canvas width=200 height=200 id="thecanvas"></canvas>
        <div><button onclick="to_image()">Draw to Image</button></div>
        <image id="theimage"></image>
    </body>
</html>

Solution 5

I created a small library that does this (along with some other handy conversions). It's called reimg, and it's really simple to use.

ReImg.fromCanvas(yourCanvasElement).toPng()

Share:
445,391

Related videos on Youtube

Wardenclyffe
Author by

Wardenclyffe

Updated on February 14, 2022

Comments

  • Wardenclyffe
    Wardenclyffe over 2 years

    I'm currently building a HTML5 web app/Phonegap native app and I can't seem to figure out how to save my canvas as an image with canvas.toDataURL(). Can somebody help me out?

    Here's the code, what's wrong with it?

    //My canvas was named "canvasSignature"

    JavaScript:


    function putImage()
    {
      var canvas1 = document.getElementById("canvasSignature");        
      if (canvas1.getContext) {
         var ctx = canvas1.getContext("2d");                
         var myImage = canvas1.toDataURL("image/png");      
      }
      var imageElement = document.getElementById("MyPix");  
      imageElement.src = myImage;                           
    
    }  
    

    HTML5:


    <div id="createPNGButton">
        <button onclick="putImage()">Save as Image</button>        
    </div>
    
    • tshm001
      tshm001 almost 12 years
      OP's question has not been answered. He clearly said this is for Phonegap / iPad. The answers given are for saving on a desktop browser.
    • Doug
      Doug over 11 years
      Not sure about phonegap, but I've done this from scratch in native iOS using JavaScript on the other end, I capture the data with .toDataURL(), then use window.location to point the browser to appname://[data url]. On the app end, the UIWebView has a delegate method that says whether or not it should load a page. I listen for appname:// and break it down when it comes in, deny the page load and capture the data url in a native string... how familiar are you with actual iOS/Objective C code?
  • Wardenclyffe
    Wardenclyffe almost 12 years
    Wow, thanks, that really helped a lot:) But how do you get a pop up save box, so that someone can save to a specific destination (like their Android images folder)?
  • Hakan Serce
    Hakan Serce almost 12 years
    It depends on the specific browser. Android browser usually download files to a specific folder directly, for instace.
  • Cees Timmerman
    Cees Timmerman almost 11 years
    Except in IE9 standards mode: "Some content or files on this webpage require a program that you don't have installed." Internet Explorer 8 and above only supports data URIs for images in CSS, <link>, and <img>: developer.mozilla.org/en-US/docs/data_URIs
  • malber
    malber almost 11 years
    Just tried it out, it will save a file with no name nor extension in Chrome.
  • SColvin
    SColvin over 10 years
    as mentioned here nihilogic.dk/labs/canvas2image setting the file name doesn't seem to be possible: "It would be really neat if somehow a filename could be attached to the data, but I've found no way to do that. For now, you have to specify the filename yourself."
  • Leabdalla
    Leabdalla over 10 years
    works fine. how can I change the name of downloaded file? it's coming just "download" and without extension. thanks!
  • Brandon
    Brandon about 10 years
    Uncaught TypeError: Object #<CanvasRenderingContext2D> has no method 'toDataURL'.
  • Kokodoko
    Kokodoko about 10 years
    In Chrome this crashes the browser. If I display the image in an image tag, it does work but the right-click menu is greyed out - so I still can't save the image.
  • Kokodoko
    Kokodoko about 10 years
    In Chrome this works, but the right-click menu is greyed out. When trying to 'drag' the image out of the browser, Chrome crashes.
  • Habrashat
    Habrashat almost 10 years
    This works great... But in Android (Default browser in Galaxy S3) it just doesn't download the image, but i get the message "Downloading..." forever.
  • Ramesh S
    Ramesh S almost 10 years
    I have save issue some one can help me see this link :stackoverflow.com/questions/25131763/…
  • Oliver Nybroe
    Oliver Nybroe over 9 years
    The link you posted is broken
  • jmknoll
    jmknoll over 8 years
    Cool library. Thanks. There's a small issue in the example documentation though. I opened an issue on Github to bring it to your attention.
  • Gediminas Masaitis
    Gediminas Masaitis about 8 years
    Perhaps you could explain the part of your code which answers the question instead of just pasting it without any comments?
  • hipkiss
    hipkiss almost 8 years
    @CeesTimmerman IE8 doesn't support canvas so there's no point to even think about it to begin with.
  • Magno C
    Magno C about 7 years
    Michael, hipkiss, Cees Timmerman : Nothing works on IE. As developer, we must have in mind to program to IE and to the rest.
  • Vishal
    Vishal about 7 years
    How can i change the path to save the image? I wish to store it in my app folder.
  • Thomas Wagenaar
    Thomas Wagenaar almost 7 years
    @Leabdalla check out my answer for that
  • KeyOfJ
    KeyOfJ almost 7 years
    groups.google.com/a/chromium.org/forum/#!topic/blink-dev/… Opening data URL like this is going to be blocked it looks like.
  • duXing
    duXing over 4 years
    Doesn't work under chrome 76/windows7. it locate to about:blank#blocked.
  • TAHA SULTAN TEMURI
    TAHA SULTAN TEMURI over 4 years
    security exception in 2020 ,can't use todataUrl
  • Crashalot
    Crashalot over 4 years
    This is wrong as the context element doesn't have a toDataURL function: developer.mozilla.org/en-US/docs/Web/API/…. You want to call toDataURL on the canvas element: developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…
  • Jeromy Adofo
    Jeromy Adofo about 4 years
    I like the fact that everything was done in JS, including the creation of the link element. It works great for automation purposes
  • Hidayt Rahman
    Hidayt Rahman almost 4 years
    Perfect solution
  • Mike Moon
    Mike Moon almost 4 years
    Thank you for this, it has helped me greatly!
  • Extrange planet
    Extrange planet about 2 years
    For security exception: img.setAttribute('crossorigin', 'anonymous');
  • Extrange planet
    Extrange planet about 2 years
    To download with extension: stackoverflow.com/a/56185896/4906752
  • Extrange planet
    Extrange planet about 2 years
    To download with file name and extension: stackoverflow.com/a/56185896/4906752
  • Cees Timmerman
    Cees Timmerman about 2 years
    No need to appendChild.
  • Cees Timmerman
    Cees Timmerman about 2 years
    No need to replace.