如何使用canvas.toDataURL()将画布另存为图像?


141

我目前正在构建HTML5网络应用程序/ Phonegap本机应用程序,似乎无法弄清楚如何使用将画布保存为图像canvas.toDataURL()。有人可以帮我吗?

这是代码,这怎么了?

//我的画布被命名为“ 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>

4
OP的问题尚未得到解答。他明确表示这是针对Phonegap / iPad的。给出的答案用于保存在桌面浏览器上。
tshm001

1
不确定phonegap,但是我在另一端使用JavaScript在本地iOS中从头开始进行操作,我使用捕获数据.toDataURL(),然后使用window.location将浏览器指向appname://[data url]。在应用程序端,UIWebView具有一个委托方法,该方法说明是否应加载页面。我会侦听appname://并将其分解,拒绝页面加载并以本机字符串捕获数据url……您对实际的iOS /目标C代码有多熟悉?
道格2012年

Answers:


121

这是一些代码。没有任何错误。

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

1
IE9标准模式下除外:“此网页上的某些内容或文件需要您尚未安装的程序。” Internet Explorer 8及更高版本仅支持CSS,<link>和<img>中图像的数据URI:developer.mozilla.org/en-US/docs/data_URIs
Cees Timmerman 2013年

45
工作良好。如何更改下载文件的名称?它只是“下载”,没有扩展名。谢谢!
Leabdalla

1
在Chrome中,这会使浏览器崩溃。如果我在图像标签中显示图像,它确实可以工作,但是右键菜单显示为灰色-因此我仍然无法保存图像。
Kokodoko

这很好用...但是在Android(Galaxy S3中的默认浏览器)中,它不会下载图像,但会永远显示消息“正在下载...”。
哈布拉斯哈特2014年

我保存的问题有人可以帮我看看这个链接:stackoverflow.com/questions/25131763/...
拉梅什小号

36

该解决方案允许您更改下载文件的名称:

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();

谢谢你,它对我有很大帮助!
Mike Moon

22

您可以使用canvas2image提示下载。

我遇到了同样的问题,这是一个简单的示例,既将图像添加到页面中又强制浏览器下载它:

<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>

2
刚刚尝试过,它将在Chrome中保存没有名称或扩展名的文件。
malber 2013年

如此处所提到的,nihilogic.dk/labs/canvas2image设置文件名似乎是不可能的:“如果能以某种方式将文件名附加到数据上,那真的很整洁,但是我发现没有办法做到这一点。现在,您必须自己指定文件名。”
SColvin

1
您发布的链接已损坏
Oliver Nybroe 2014年

9

您可以尝试一下;创建一个虚拟HTML锚,然后从那里下载图片,例如...

// 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();
}

1
我喜欢所有事情都在JS中完成的事实,包括link元素的创建。它非常适合自动化用途
Jeromy Adofo

完美的解决方案
Hidayt Rahman

8

我创建了一个小型库来执行此操作(以及其他一些方便的转换)。它称为reimg,使用起来非常简单。

ReImg.fromCanvas(yourCanvasElement).toPng()


很酷的图书馆。谢谢。但是,示例文档中存在一个小问题。我在Github上发表了一个问题,以引起您的注意。
jmknoll

7

为我工作:(仅适用于Google Chrome)

<html>
<head>
    <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 downloadImage()
            {
                var canvas = document.getElementById("thecanvas");
                var image = canvas.toDataURL();

                var aLink = document.createElement('a');
                var evt = document.createEvent("HTMLEvents");
                evt.initEvent("click");
                aLink.download = 'image.png';
                aLink.href = image;
                aLink.dispatchEvent(evt);
            }
    </script>
</head>
<body onload="draw()">
    <canvas width=200 height=200 id="thecanvas"></canvas>
    <div><button onclick="downloadImage()">Download</button></div>
    <image id="theimage"></image>
</body>
</html>

也许您可以解释代码中回答问题的部分,而不仅仅是将其粘贴而没有任何注释?
Gediminas Masaitis

6

类似于1000Bugy的答案,但更简单,因为您不必动态定位并手动分配click事件(加上IE修复程序)。

如果将下载按钮设为锚,则可以在运行默认锚功能之前立即劫持它。因此,onAnchorClick您可以将anchor href设置为canvas base64图像,并将anchal download属性设置为您要命名图像的名称。

这在(当前)IE中不起作用,因为它没有实现download属性,并且阻止了数据uri的下载。但这可以通过使用来解决window.navigator.msSaveBlob来解决。

所以,你的锚单击事件处理程序将被作为跟随(其中anchorcanvasfileName有范围查找):

function onClickAnchor(e) {
  if (window.navigator.msSaveBlob) {
    window.navigator.msSaveBlob(canvas.msToBlob(), fileName);
    e.preventDefault();
  } else {
    anchor.setAttribute('download', fileName);
    anchor.setAttribute('href', canvas.toDataURL());
  }
}

这是一个小提琴


1

而不是imageElement.src = myImage;你应该使用window.location = myImage;

甚至在那之后,浏览器也会显示图像本身。您可以右键单击并使用“保存链接”下载图像。

检查此链接以获取更多信息。


哇,谢谢,这确实有很大帮助:)但是,您如何获得一个弹出的保存框,以便某人可以保存到特定的目的地(例如其Android图像文件夹)?
Wardenclyffe 2012年

这取决于特定的浏览器。Android浏览器通常会直接将文件下载到特定文件夹以进行安装。
哈坎·塞斯

在Chrome中可以使用,但是右键菜单显示为灰色。尝试从浏览器中“拖动”图像时,Chrome崩溃。
Kokodoko

groups.google.com/a/chromium.org/forum/#!topic/blink-dev/…看起来像这样的打开数据URL将会被阻止。
KeyOfJ

0

在Cordova中运行时,不能使用前面提到的方法下载图像。您将需要使用Cordova File Plugin。这将允许您选择保存位置,并利用不同的持久性设置。此处的详细信息:https : //cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

或者,您可以将映像转换为base64,然后将字符串存储在localStorage中,但是如果您有很多映像或高分辨率,这将很快填满您的配额。


-9

@Wardenclyffe和@SColvin,你们都试图使用画布而不是使用画布的上下文来保存图像。两者都应尝试ctx.toDataURL(); 试试这个:

var canvas1 = document.getElementById("yourCanvasId");  <br>
var ctx = canvas1.getContext("2d");<br>
var img = new Image();<br>
img.src = ctx.toDataURL('image/png');<br>
ctx.drawImage(img,200,150);<br>

您也可以参考以下链接:

http://tutorials.jenkov.com/html5-canvas/todataurl.html

http://www.w3.org/TR/2012/WD-html5-author-20120329/the-canvas-element.html#the-canvas-element


未捕获的TypeError:对象#<CanvasRenderingContext2D>没有方法'toDataURL'。
Brandon Aubie 2014年

这是错误的,因为context元素没有toDataURL功能:developer.mozilla.org/en-US/docs/Web/API/…。您要拨打toDataURL的canvas元素上:developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/...
Crashalot
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.