如何从画布中保存图像

6

最近我一直在尝试使用Webrtc创建照片亭,几乎完成了所有的代码,但我还没有找到一种在捕获图像后保存图像的方法。

目前为止,这是我最接近实现目标的方式:

 <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>fotogoof</title>
    <link rel="Stylesheet" href="css/bootstrap.css"/>
    <link rel="Stylesheet" href="css/style.css"/>
    <script type="text/javascript">
            window.onload = function () {
                var img = document.getElementById('screenshot');
                var button = document.getElementById('saveImage');
                img.src = '';
                img.onload = function () {
                    button.removeAttribute('disabled');
                };
                button.onclick = function () {
                    window.location.href = img.src.replace('image/png', 'image/octet-stream');
                };
            };
    </script>
    </head>
    <div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
      <div class="container">
        <h2 class="brand">Html5 Photobooth</h1>
      </div>
    </div>
    </div>
    <div class="container" id="body-wrap">
    <div class="container" id="main">
      <div class="span10">
        <div id="video-container">
        <canvas width="400" height="320" class="mask"></canvas>
          <div id="counter">
          </div>
        </div>  
        <br><div id="pic-holder" class="pull-left"><img id="screenshot"></div></br>
        <input id="saveImage" type="button" value="save image" disabled="disabled"/>
      </div>
    </div>
   </div>   
    </div>

代码基本上是将网络摄像头流传送到画布元素中。按下空格键触发截取屏幕截图,然后以图像形式显示。因为我无法提供所下载文件的确切源,所以该按钮仅在浏览器中打开图像而不起作用。我真的很感谢您提供有关如何解决此问题的建议。先行致谢。
我已经使用以下代码成功地从画布中捕获了流程图像:
document.addEventListener ('keydown', function (event) {
        if(event.keyCode == 32) {
         document.querySelector('#screenshot').src = canvas.toDataURL('image/webp')
        }
})

我想知道如何让用户从那里保存图像到他们的电脑上。

你需要为画布元素添加一个ID,这样我的答案才能起作用。 - Roy M J
1
可能是如何将画布保存为PNG图像?的重复问题。 - Cees Timmerman
4个回答

17

如果我理解正确,您想要下载(即为用户提供保存对话框以选择位置)图像到用户的计算机上?

如果是这样,您可以使用以下代码片段:

function download(canvas, filename) {

    /// create an "off-screen" anchor tag
    var lnk = document.createElement('a'),
        e;

    /// the key here is to set the download attribute of the a tag
    lnk.download = filename;

    /// convert canvas content to data-uri for link. When download
    /// attribute is set the content pointed to by link will be
    /// pushed as "download" in HTML5 capable browsers
    lnk.href = c.toDataURL();

    /// create a "fake" click-event to trigger the download
    if (document.createEvent) {

        e = document.createEvent("MouseEvents");
        e.initMouseEvent("click", true, true, window,
                         0, 0, 0, 0, 0, false, false, false,
                         false, 0, null);

        lnk.dispatchEvent(e);

    } else if (lnk.fireEvent) {

        lnk.fireEvent("onclick");
    }
}

现在你只需要提供一个默认的文件名并调用函数即可:
download(myCanvas, 'untitled.png');

如果你想直接将文件保存到用户的硬盘上,由于安全原因,你无法这样做。

话虽如此,你仍然可以使用本地存储,例如文件 API 或 Indexed DB - 但由于这些都是沙盒化的,所以你和用户只能通过浏览器访问“文件”,可能不太方便。


+1 很好的回答。鉴于画布是呈现数据和娱乐的绝佳媒介,浏览器制造商似乎应该提供更直接的画布到本地磁盘保存方法——也许是通过要求用户在警告对话框中点击“确定”来满足安全问题的需求。 - markE
谢谢@markE。我同意,像“允许此网站保存到[此]位置”这样的功能会很棒。 - user1693593
抱歉,我有点困惑。代码中的“download(myCanvas,'untitled.png');”部分是紧跟在“function download(canvas,filename)”部分之后吗? - user2724072
@user2724072 函数...只是定义函数并使其在定义的作用域中可用,因此只要可以访问函数定义的作用域,您就可以从代码中的任何位置调用 download(..)。例如,如果您将函数 download() 放在全局作用域中,则可以随时从任何地方调用 download()。JavaScript 在开始执行任何代码之前解析函数定义。或者这样说:只要需要时调用它,只要函数被定义,无论调用是在之前还是之后都没有关系。 - user1693593
我正在使用这个类似的代码来保存YouTube视频。在Chrome上它可以工作,并使用自定义文件名保存文件,但是在Firefox 30.0上,它会将视频下载为默认文件名“videoplayback”,而不是自定义文件名。有没有人解决过这样的问题?谢谢。 - frank

0

0

我曾经遇到过这个问题,以下是最佳解决方案,无需任何外部或附加脚本库: 在Javascript标签或文件中创建此函数: 我们假设这里的canvas是您的画布:

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文件的body部分指定按钮:

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

这个功能正常,下载链接看起来像一个按钮。


-1
关于第一个任务,您可以使用canvas对象支持的toDataUrl方法将画布内容导出为图像。
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
    var ctx = canvas.getContext("2d");                // Get the context for the canvas.
    var myImage = canvas.toDataURL("image/png");      // Get the data as an image.
}

var image = document.getElementById("screenshot");  // Get the image object.
image.src = myImage; 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接