admin管理员组

文章数量:1394099

When drawImage() is used to draw something on to a canvas element, can the canvas be treated as an image?

When I right click on the drawn canvas element it dosent show the "Save image as" option.

This is the right click menu I see:

What should be done to have the "save image as" option available?

When drawImage() is used to draw something on to a canvas element, can the canvas be treated as an image?

When I right click on the drawn canvas element it dosent show the "Save image as" option.

This is the right click menu I see:

What should be done to have the "save image as" option available?

Share asked Apr 16, 2015 at 12:09 BeckyBecky 5,6159 gold badges44 silver badges79 bronze badges 5
  • 1 This is the default browser implementation. You need to listen for 'right click' on your canvas and display your own context menu, which will perform image saving – Vigneswaran Marimuthu Commented Apr 16, 2015 at 12:10
  • @VigneswaranMarimuthu: thanks. How do I do a listener for 'right click' on the canvas to display an own context menu – Becky Commented Apr 16, 2015 at 12:13
  • 1 Canvas normally dont change your DOM, so it s impossible to do a right clic on DOM image so you have to code it by yourself. Example : davidwalsh.name/html5-context-menu (i dont test it) – Benjamin Poignant Commented Apr 16, 2015 at 12:14
  • Wouldn't it be easier to just overlay an image tag over the canvas with the base64 from the canvas as source – adeneo Commented Apr 16, 2015 at 12:23
  • @adeneo thanks. What you say is correct but how can the base64 string be generated? Like this? var theIMG = document.getElementById("dawenCanvas"); var cv = theIMG.getContext("2d"); var image = cv.toDataURL(); image = image.replace('data:image/png;base64,', ''); ? What if it throws a security error like SecurityError: The operation is insecure ? – Becky Commented Apr 16, 2015 at 13:49
Add a ment  | 

3 Answers 3

Reset to default 6

So, this depends a lot on the browser and how it works and in general I wouldn't advise messing with this, but if you have to get this working for one reason or another there is a way: You can 'simply' convert the canvas to an <img> element after each draw and show the <img> element instead.

var canvas = document.getElementById('exampleCanvas'); //Hidden <canvas> element
var imageFoo = document.getElementById('exampleImg'); //Visible <img> element

And then after each draw is finished:

imageFoo.src = canvas.toDataURL();

The disadvantage here is that you will lose a lot of speed, so do not use this for animated canvases or anything like that.

The "Save as image.." is something some browsers (incl. Chrome and Firefox) includes in the context menu for convenience. It's not a standard in any way though.

You could emulate the right-click and provide a custom context menu with the option of save as, however, here is the caveat:

For this to work you need to have the download attribute in the A-tag supported as well. The problem is that for example IE, which does not provide the "Save as image.." option in the menu, neither support the download attribute.

The better option is probably to insert an actual image instead of or on top of the canvas when pleted (depending on how the alpha channel is used). This may not always be feasible if the content is dynamic and constantly updating, and there is CORS restrictions at play as well for images loaded from external sources.

In conclusion: There is little one can do to make a solid workaround for this. It is and will be a browser feature pretty much (and being selective about which browser to support is already the case with the feature itself, so no gain here...).

You can do this if you want to download the picuture on the canvas:

<!doctype html>
<html lang="gb">
    <head>
    </head>
    <body>
        <canvas id="test"></canvas>
        <script>
            var canvas = document.getElementById('test');
            var ctx = canvas.getContext("2d");
            ctx.font = "30px Arial";
            ctx.fillText("Noel Rocks",10, 50);

            canvas.addEventListener("contextmenu", function(ev){
            ev.preventDefault();
            var image_png = canvas.toDataURL("image/png");

            var download = document.createElement('a');
            download.href = image_png;
            download.download = "canvas.png";

            var evObj = document.createEvent('MouseEvents');
            evObj.initEvent( "click", true, false );
            download.dispatchEvent(evObj)

            }, false);
        </script>
    </body>
</html>

Basically it overwrites the context menu, sets up a link with the canvas as a png and then sends the click event to the link. I have used the Download attribute which isn't available in any version of IE or Safari so might not really be fit for general use.

本文标签: javascriptSave as image when right clicked on canvasStack Overflow