How to save an image from canvas

2019-01-24 12:46发布

Recently I've been attempting to create a photo booth by relying on Webrtc and have nearly completed all of the code except I've not been able to figure out a way to save the image after it has been captured.

This is the closest I've come so far to achieving my goal:

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

The code is essentially taking the webcam stream and feeding it into a canvas element. Pressing the space button triggers a screenshot to be taken, which then appears as an image. Because I'm unable to provide the exact source of the file that is being downloaded the button only opens the image in another tab in the browser instead of functioning properly. I would really appreciate some input as to how I can resolve this. Thanks in advance.

I've already managed to do capture the stream from the canvas in an image with this bit of code:

document.addEventListener ('keydown', function (event) {
        if(event.keyCode == 32) {
         document.querySelector('#screenshot').src = canvas.toDataURL('image/webp')
        }
})

What I want to know is how to enable the user to save the image onto their computer from there.

5条回答
唯我独甜
2楼-- · 2019-01-24 13:06

I had this problem and this is the best solution without any external or additional script libraries: In Javascript tags or file create this function: We assume here that canvas is your 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);

    }

In the body part of your HTML specify the button:

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

This is working and download link looks like a button.

查看更多
Luminary・发光体
3楼-- · 2019-01-24 13:07

I don't think it's possible for IE without involving a server side script. Here's a good writeup on how to do it that way.

查看更多
看我几分像从前
4楼-- · 2019-01-24 13:08

I've now included this in my html code:

<div id="download">
    <p><label for="imageName">Image name:</label> <input type="text" placeholder="My Photobooth Pic" id="imageName"></p>
    <p>If you want, you can <button>Download</button> the image.</p>
</div>

and I've updated my javascript code to include this now:

var _filenameInput = document.getElementById('imageName'),
var _downloadButton = document.querySelector('#download button'),

document.addEventListener ('keydown', function (event) {
            if(event.keyCode == 32) {
             document.querySelector('#screenshot').src = canvas.toDataURL('image/webp')
        }

 })

_downloadButton.addEventListener('click', _downloadImage);

var _downloadImage = function(e) {

    /** do download **/
    var imageDataUrl = canvas.toDataURL('image/png').substring(22);
    var byteArray = Base64Binary.decode(imageDataUrl);
    var blob = new Blob([byteArray], {type:'image/png'});
    var url = window.URL.createObjectURL(blob);

    var link = document.createElement('a');
    link.setAttribute('href', url);
    var filename = _filenameInput.value;
    if (!filename) {
        filename = _filenameInput.getAttribute('placeholder');
    }
    link.setAttribute('download', filename + '.png');
    link.addEventListener('click', function() {
        _downloadButton.className = 'downloaded';
    });

    var event = document.createEvent('MouseEvents');
    event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
    link.dispatchEvent(event);
};
})();
};

It's still no good though. What do you guys think? I really appreciate the help.

查看更多
疯言疯语
5楼-- · 2019-01-24 13:09

If I understand correctly you want to download (ie. provide a save dialog for the user to pick a location) the image to user's machine?'

If so you can use this snippet:

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");
    }
}

Now all you need to do is to provide a default file name and call the function:

download(myCanvas, 'untitled.png');

If you rather than this mean save directly to user's harddisk then you can't due to security reasons.

That being said, there is always the option of using local storage such as File API or Indexed DB - but as these are sand-boxed you and the user will only have access to the "files" through the browser so perhaps not so convenient.

查看更多
时光不老,我们不散
6楼-- · 2019-01-24 13:25

Regarding the first task, you can export the canvas content to an image with toDataUrl method supported by the canvas object.

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; 
查看更多
登录 后发表回答