如何将画布保存为png图像?

时间:2012-06-20 03:10:55

标签: javascript html5 canvas

我有一个带有绘图的画布元素,我想创建一个按钮,当点击它时,它会将图像保存为png文件。所以它应该打开保存,打开,关闭对话框......

我使用此代码

var canvas = document.getElementById("myCanvas");
window.open(canvas.toDataURL("image/png"));

但是当我在IE9中测试它时,会打开一个新窗口,说“无法显示网页” 它的网址是:

数据:图像/ PNG; BASE64,iVBORw0KGgoAAAANSUhEUgAAAmAAAABpCAYAAACd + 58xAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAADRwSURBVHhe7V0HgBVF0q7ZJSlJwRxAPUFRD39RFLN34qGnnomoqIjhzBlFPROIgsoZzogR5AQEzJ4BPFAUEUwgJjgQkCQKooggaf / 6el6 / 6ZnpSW / zUn237u5MdXX1172 + z6rqaqeEG6VsJet + PDW / vkdrfx3H3yfT2tVzaP26X6hkw1q / BoeI / 280 / 29JwznZxJPUyXtBQBAQBAQBQaBcECjefmi56BWlZYtAeqajx / WokfrJYEqOIikOFRfXoVq161PtOk2odu0t + ectqKiojnrntWhC46QhYOtXfUarl79Ivy9 / ldau + H + TX / 8b2SbjJ07pWFQy2Uqnp2yXSrQJAoKAICAICALJCAgBS8ao8iTi / UvpSZlBxiwqwWOKimsxCWtEdettR3XqbEfFtRonkrBYArZh3fe0 + senadWyEbRm1UzasP53K45ZiFc84RKyVXkbVUYWBAQBQUAQyIqAELCsiFW2fDQpSyZk8UQMMysqKmaPWCOqt8mOVK / eTuQU1YuccCQBW7dyIq38 / J5A / fN的/ ad3a5QGXmqsvLfGKJl0ZCFdONEOPyl5lGV8QEAQEAUGghiMgBKzqLHCeHqVOrILtduF4MpZExEqoVq167A3bmjap34J / bmoFqcj2dM3Pr9GK + b1p5bJXmXz9nEC + 3FiorYF4hcmXlo + gUrk +微米/ + E + QoVWfxxRJBQBAQBAQBQUAQqBwE8uzCwiMiaEqOWYR5jJ2 / 6Hl58nYHk0Pr1v1Ov62cTytXfE5r1yyyc6RgDhjI16 + L + tLqFZ9xnteGUKc0Xi876YpYkFDCfpqFEz9YGpRERhAQBAQBQaB8ERAPWPnim157JreX6 / eK7eJ / Ge0RS8oPc9gT1pTqN2jFocltfdPxecBU2HH xgBTky + 71CjPGCO + YyU4j0TU9ZcGf0y + JSAoCgoAgIAgIAoJATUcgG2dQ0jpKZ / XP + PlLtEcs3huGQhO / r17K3rBvuGrEUt8i5HPAkHC / Yt6lKuwYKiuRM9TtGbY0rcerTBLwC / KY1fSNJ / MTBAQBQUAQqAwExANWGaiHx0z2aJl9CknET + MRc2XsVSKKaNP6O1CDhvtwYn5dJZf3gOG0IxLuS0e + LB4vw9sVhiwmHywmF6xqLLdYIQgIAoKAICAICAJVAQHTo2XmkNtzv6K5R7RXLOwRs3MaW + 47SNkG9oRxZQmun6qbImCo84VSE + 5pR3 / zvFZJni / 7e8tTHiCeqCkAqsKKig2CgCAgCAgCgoAgUG0RCBKzMLmwkzHdL4pk4XlUAn7Uu3XrVtPqVfO4lurPSq0KQa5cdAv9snBgqM5XFPlKSsSPM8o3mcxES2hZtf0rEMMFAUFAEKiBCEgIsqotavpk / OiwZViHPQk / LgHfHo5EnbCGjVpxeYo9yNmw9oeSn2YeTatWTPNzozzX8ZOeWPJlJVRJnrOoxUtJtmLEUmqoartH7BEEBAFBQBCoJggIASu / hUqkUokC2rZkwSSCBU12wpadhNXbpAk13vwwKlJ3O / L1QmYrxPNlDxuGyVtyIn6K8KSZHwY3XsRX + W0L0VyTEPjwM6KuFxN1uiB6Vkv48MpdjxLt9ieieQvscuvWE13eh2jnQ9zv + F2aICAICAKCQGEIRH22559H5IqnDTMGeU / SgUJ7WNLjOVH9g8 / Xrv2Fa4P9SM6K7y4t + WXRw76sfVc42fPV936iJ5 + LKrbqTU0P3rA + 0dZbEh20L9HJHYj23I2oVrHFT5U5NFnY4m6svUA0Pvo8efbvjCBqtr0nN + IVot4Dkvv1v5aoy / HJcpUpsfI3olffdknV0uWuJfv9kWjkw55VIFAfM073PE4EkqZbEBf9HMTs8C6e3KhHiPbdqzJnKWMLAoJAeSMgHrDyRrj0 + rOEGvV oYY9Y0inIeE + YQQ + cqGGj3dgDtvJjC / mKm7BHmG68lGjO + 0T

任何人都知道如何解决这个问题?

11 个答案:

答案 0 :(得分:51)

试试这个:

var c=document.getElementById("alpha");
var d=c.toDataURL("image/png");
var w=window.open('about:blank','image from canvas');
w.document.write("<img src='"+d+"' alt='from canvas'/>");

这会在新页面上显示画布中的图片,但如果您设置了open popup in new tab,则会在地址栏中显示about:blank

编辑: - 虽然window.open("<img src='"+ c.toDataURL('image/png') +"'/>")在FF或Chrome中不起作用,但是后续工作虽然渲染与画布上显示的有些不同,但我认为透明度是个问题:

window.open(c.toDataURL('image/png'));

答案 1 :(得分:24)

FileSaver.js应该可以在这里帮助你。

var canvas = document.getElementById("my-canvas");
// draw to canvas...
canvas.toBlob(function(blob) {
    saveAs(blob, "pretty image.png");
});

答案 2 :(得分:11)

我使用此解决方案设置文件名

HTML:

<a href="#" id="downloader" onclick="download()" download="image.png">Download!</a>
<canvas id="canvas"></canvas>

JavaScript的:

function download(){
    document.getElementById("downloader").download = "image.png";
    document.getElementById("downloader").href = document.getElementById("canvas").toDataURL("image/png").replace(/^data:image\/[^;]/, 'data:application/octet-stream');
}

答案 3 :(得分:6)

我遇到了这个问题,这是没有任何外部或附加脚本库的最佳解决方案: 在Javascript标签或文件中创建此功能: 我们假设画布是你的画布:

function download(){
        var download = document.getElementById("download");
        var image = document.getElementById("canvas").toDataURL("image/png")
                    .replace("image/png", "image/octet-stream");
        download.setAttribute("href", image);

    }

在HTML的正文部分指定按钮:

<a id="download" download="image.png"><button type="button" onClick="download()">Download</button></a>

这是工作和下载链接看起来像一个按钮。在Firefox和Chrome中测试过。

答案 4 :(得分:3)

我可能发现了一种更好的方法,可以不强迫用户右键单击并“将图像另存为”。实时将画布base64代码绘制到链接的href并进行修改,以便下载自动开始。我不知道它是否普遍与浏览器兼容,但是it should work with the main/new browsers

var canvas = document.getElementById('your-canvas');
    if (canvas.getContext) {
        var C = canvas.getContext('2d');
    }

$('#your-canvas').mousedown(function(event) {
    // feel free to choose your event ;) 

    // just for example
    // var OFFSET = $(this).offset();
    // var x = event.pageX - OFFSET.left;
    // var y = event.pageY - OFFSET.top;

    // standard data to url
    var imgdata = canvas.toDataURL('image/png');
    // modify the dataUrl so the browser starts downloading it instead of just showing it
    var newdata = imgdata.replace(/^data:image\/png/,'data:application/octet-stream');
    // give the link the values it needs
    $('a.linkwithnewattr').attr('download','your_pic_name.png').attr('href',newdata);

});

您可以将<a>包裹在您想要的任何地方。

答案 5 :(得分:0)

试试这个:

jQuery('body').after('<a id="Download" target="_blank">Click Here</a>');

var canvas = document.getElementById('canvasID');
var ctx = canvas.getContext('2d');

document.getElementById('Download').addEventListener('click', function() {
    downloadCanvas(this, 'canvas', 'test.png');
}, false);

function downloadCanvas(link, canvasId, filename) {
    link.href = document.getElementById(canvasId).toDataURL();
    link.Download = filename;
}

您可以将此代码放在firefox或chrom中的控制台中,并在上面的脚本中更改了canvas标记ID并在控制台中运行此脚本。

执行此代码后,您将在html页面底部看到链接为文本“单击此处”。单击此链接并在新窗口中将画布图作为PNG图像打开以保存图像。

答案 6 :(得分:0)

提交一个包含canvas值toDataURL('image / png')的输入的表单,例如

// JAVASCRIPT

    var canvas = document.getElementById("canvas");
    var url = canvas.toDataUrl('image/png');

将url的值插入表单元素上的隐藏输入。

// PHP

    $data = $_POST['photo'];
    $data = str_replace('data:image/png;base64,', '', $data);
    $data = base64_decode($data);
    file_put_contents("i".  rand(0, 50).".png", $data);

答案 7 :(得分:0)

完整的HTML代码。剪切+粘贴到新的.HTML文件中:

包含两个例子:

  1. HTML文件中的画布。
  2. 使用Javascript动态创建的画布。
  3. 测试:

    1. Internet Explorer
    2. * Edge(标题名称未显示)
    3. 火狐
    4. <!DOCTYPE HTML >
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title> #SAVE_CANVAS_TEST# </title>
          <meta 
              name   ="author" 
              content="John Mark Isaac Madison"
          >
          <!-- EMAIL: J4M4I5M7 -[AT]- Hotmail.com -->
      </head>
      <body>
      
      <div id="about_the_code">
          Illustrates:
          <ol>
          <li>How to save a canvas from HTML page.     </li>
          <li>How to save a dynamically created canvas.</li>
          </ol>
      </div>
      
      <canvas id="DOM_CANVAS" 
              width ="300" 
              height="300"
      ></canvas>
      
      <div id="controls">
          <button type="button" style="width:300px;"
                  onclick="obj.SAVE_CANVAS()">
              SAVE_CANVAS ( Dynamically Made Canvas )
          </button>
      
          <button type="button" style="width:300px;"
                  onclick="obj.SAVE_CANVAS('DOM_CANVAS')">
              SAVE_CANVAS ( Canvas In HTML Code )
          </button>
      </div>
      
      <script>
      var obj = new MyTestCodeClass();
      function MyTestCodeClass(){
      
          //Publically exposed functions:
          this.SAVE_CANVAS = SAVE_CANVAS;
      
          //:Private:
          var _canvas;
          var _canvas_id = "ID_OF_DYNAMIC_CANVAS";
          var _name_hash_counter = 0;
      
          //:Create Canvas:
          (function _constructor(){
              var D   = document;
              var CE  = D.createElement.bind(D);
              _canvas = CE("canvas");
              _canvas.width = 300;
              _canvas.height= 300;
              _canvas.id    = _canvas_id;
          })();
      
          //:Before saving the canvas, fill it so
          //:we can see it. For demonstration of code.
          function _fillCanvas(input_canvas, r,g,b){
              var ctx = input_canvas.getContext("2d");
              var c   = input_canvas;
      
              ctx.fillStyle = "rgb("+r+","+g+","+b+")";
              ctx.fillRect(0, 0, c.width, c.height);
          }
      
          //:Saves canvas. If optional_id supplied,
          //:will save canvas off the DOM. If not,
          //:will save the dynamically created canvas.
          function SAVE_CANVAS(optional_id){
      
              var c = _getCanvas( optional_id );
      
              //:Debug Code: Color canvas from DOM
              //:green, internal canvas red.
              if( optional_id ){
                  _fillCanvas(c,0,255,0);
              }else{
                  _fillCanvas(c,255,0,0);
              }
      
              _saveCanvas( c );
          }
      
          //:If optional_id supplied, get canvas
          //:from DOM. Else, get internal dynamically
          //:created canvas.
          function _getCanvas( optional_id ){
              var c = null; //:canvas.
              if( typeof optional_id == "string"){
                  var id = optional_id;
                  var  d = document;
                  var c  = d.getElementById( id );
              }else{
                  c = _canvas; 
              }
              return c;
          }
      
          function _saveCanvas( canvas ){
              if(!window){ alert("[WINDOW_IS_NULL]"); }
      
              //:We want to give the window a unique
              //:name so that we can save multiple times
              //:without having to close previous
              //:windows.
              _name_hash_counter++              ; 
              var NHC = _name_hash_counter      ;
              var URL = 'about:blank'           ;
              var name= 'UNIQUE_WINDOW_ID' + NHC;
              var w=window.open( URL, name )    ;
      
              if(!w){ alert("[W_IS_NULL]");}
      
              //:Create the page contents,
              //:THEN set the tile. Order Matters.
              var DW = ""                        ;
              DW += "<img src='"                 ;
              DW += canvas.toDataURL("image/png");
              DW += "' alt='from canvas'/>"      ;
              w.document.write(DW)               ;
              w.document.title = "NHC"+NHC       ;
      
          }
      
      }//:end class
      
      </script>
      
      </body>
      <!-- In IE: Script cannot be outside of body.  -->
      </html>
      

答案 8 :(得分:0)

要容纳所有三点:

  • 按钮
  • 将图像另存为png文件
  • 打开“保存,打开,关闭”对话框

文件对话框是浏览器中的设置。

对于按钮/保存部分,将以下功能(从其他答案中总结出来)分配给onclick按钮:

function DownloadCanvasAsImage(){
    let downloadLink = document.createElement('a');
    downloadLink.setAttribute('download', 'CanvasAsImage.png');
    let canvas = document.getElementById('myCanvas');
    let dataURL = canvas.toDataURL('image/png');
    let url = dataURL.replace(/^data:image\/png/,'data:application/octet-stream');
    downloadLink.setAttribute('href', url);
    downloadLink.click();
}

Example on Codepen

另一种更干净的方法是使用Canvas.toBlob()

function DownloadCanvasAsImage(){
    let downloadLink = document.createElement('a');
    downloadLink.setAttribute('download', 'CanvasAsImage.png');
    let canvas = document.getElementById('myCanvas');
    canvas.toBlob(function(blob) {
      let url = URL.createObjectURL(blob);
      downloadLink.setAttribute('href', url);
      downloadLink.click();
    });
}

Example on Codepen

这两种解决方案都不是100%跨浏览器兼容的,因此请检查客户端

答案 9 :(得分:0)

我真的很喜欢Tovask的答案,但是由于该函数的名称为downloadthis answer解释了原因),所以它不起作用。我也看不出将“ data:image / ...”替换为“ data:application / ...”的意义。

以下代码已在Chrome和Firefox中进行了测试,并且似乎在两者中都能正常工作。

JavaScript:

function prepDownload(a, canvas, name) {
    a.download = name
    a.href = canvas.toDataURL()
}

HTML:

<a href="#" onclick="prepDownload(this, document.getElementById('canvasId'), 'imgName.png')">Download</a>
<canvas id="canvasId"></canvas>

答案 10 :(得分:-1)

var canvasId = chart.id + '-canvas';
var canvasDownloadId = chart.id + '-download-canvas';
var canvasHtml = Ext.String.format('<canvas id="{0}" width="{1}" height="{2}"></canvas><a id="{3}"/>',
canvasId,
chart.getWidth(),
chart.getHeight(),
canvasDownloadId);
var canvasElement = reportBuilder.add({ html: canvasHtml });

var canvas = document.getElementById(canvasId);

var canvasDownload = document.getElementById(canvasDownloadId);
canvasDownload.href = chart.getImage().data;
canvasDownload.download = 'chart';

canvasDownload.click();
相关问题