【问题标题】:How to save canvas on Right-Click dialog as jpg如何将右键单击对话框上的画布保存为 jpg
【发布时间】:2020-04-02 11:09:15
【问题描述】:

我正在使用此代码从我网站中的视频URL 中将图像捕获为画布:

var videoId = 'video';
var scaleFactor = 0.55; // increase or decrease size
var snapshots = []; 
/**
 * Captures a image frame from the provided video element.
 *
 * @param {Video} video HTML5 video element from where the image frame will be captured.
 * @param {Number} scaleFactor Factor to scale the canvas element that will be return. This is an optional parameter.
 *
 * @return {Canvas}
 */

function capture(video, scaleFactor) {
    if(scaleFactor == null){
        scaleFactor = 1;
    }

    var w = video.videoWidth * scaleFactor;
    var h = video.videoHeight * scaleFactor;
    var canvas = document.createElement('canvas');
        canvas.width  = w;
        canvas.height = h;
    var ctx = canvas.getContext('2d');
        ctx.drawImage(video, 0, 0, w, h);
    var uniq = 'img_' + (new Date()).getTime();
    canvas.setAttribute('id', uniq);

  return canvas ;

}

/**
 * Invokes the <code>capture</code> function and attaches the canvas element to the DOM.
 */
function shoot(){
    var video  = document.getElementById(videoId);
    var output = document.getElementById('output');
    var canvas = capture(video, scaleFactor);

    snapshots.unshift(canvas);
    output.innerHTML = '' ;

    for(var i=0; i<10; i++){
       output.appendChild(snapshots[i]);

    }
}

我的两个问题:

1 - 目前,浏览器对待 &lt;canvas&gt; 就像对待 &lt;div&gt; 一样,这使得无法将任何生成的画布保存为图像,因为当我在每个人上 right-click 时,它总是打开窗口对话框这里我要选择Save image as...

2 - 默认情况下,Windows right-click 对话框始终打开将图像另存为 transfer.png 的选项,我想使用其ID attribute (var uniq) 和 jpg 扩展名保存图像。

我需要的示例:

输出画布是这样的:&lt;canvas width="352" height="198" id="img_1575807516362"&gt;&lt;/canvas&gt;

我希望right-click 打开窗口对话框,提供像这样img_1575807516362.jpg 保存图像。

或者,最好为每个画布设置一个下载按钮,以将canvas 导出为类似transfer.jpg 的图像。

是否可以使用此代码进行此操作?

【问题讨论】:

    标签: javascript canvas html5-canvas export jpeg


    【解决方案1】:

    提前道歉。我花了一些时间,但我想确保它正常工作。我不确定是否有办法让 Windows 对话框保存到文件(它会在哪里拉起另存为...提示),但您绝对可以创建一个下载按钮来执行此操作。

    下载图片

    首先,我们需要创建一个下载按钮:

    <button onmousedown="download()">Download</button>
    

    其次,我们可以创建一个函数来通过密钥下载图像。 最简单的方法是创建一个可下载的&lt;a&gt; 标签:

    var download = function(){
        var link = document.createElement('a'); //Creates an 'a' element
        var thisCanvas = document.getElementsByTagName('canvas')[0]; //gets the first canvas element on the page, assuming the canvas you want to download is this element. 
        link.download = `${thisCanvas.id}.jpeg`; //Gives the download an output link
        link.href = thisCanvas.toDataURL("image/jpeg") //Gives the data to the link
        link.click(); //Clicks the 'a' element we created
        }
    

    如果您想询问用户是否要下载,您可以使用:

    var download = function() {
        if (window.confirm("Would you like to download this frame?")) { 
            var link = document.createElement('a'); //Creates an 'a' element
            var thisCanvas = document.getElementsByTagName('canvas')[0]; //Gets the canvas
            link.download = `${thisCanvas.id}.jpeg`; //Gives the download an output link
            link.href = thisCanvas.toDataURL("image/jpeg") //Gives the data to the link
            link.click(); //Clicks the 'a' element we created
        }
    }
    

    您也可以随时使用link.download = imageName + ".jpeg"更改图像文件的名称

    在 JS 中创建一个按钮

    编辑:如果您想在 javascript 而不是 html 中创建按钮,您可以执行以下操作:

    var createbutton = function() {
        var b = document.createElement('button'); //Creates the button
        b.onmousedown = function() { //Creates an onmousedown event for the button
            download(); //This is the download function above
        }
        b.innerHTML = "Download"; //Gives the button Text
        //Here, you can insert button styles using: b.style 
        document.body.appendChild(b); //Appends the button to the body
    }
    

    您可以在需要创建下载按钮时调用此函数。此函数在正文末尾创建一个按钮,但您可以更改位置:

       //Where it says document.body.appendChild(b); , replace it with:
       document.getElementById(`myCustomId`).appendChild(b);
       //This places the button in any element on the page with 'myCustomId' 
    

    画布 onmousedown 事件,并下载所有图像

    编辑(2):

    如果您在snapshots 中创建了多个画布,则可以执行以下操作来下载所有快照:

    var download = function(){
        var link = document.createElement('a'); //Creates an 'a' element
        snapshots.forEach(snap => {
            link.download = `${snap.id}.jpeg`; //Gives the download an output link
            link.href = snap.toDataURL("image/jpeg") //Gives the data to the link
            link.click(); //Clicks the 'a' element we created
        });
    
        }
    

    如果您想一次下载一张图片,您可以在添加图片时给他们一个 onmousedown 事件。让我们编辑下载功能来支持这个:

    var download = function(canvas){
        var link = document.createElement('a'); //Creates an 'a' element
        link.download = `${canvas.id}.jpeg`; //Gives the download an output link
        link.href = canvas.toDataURL("image/jpeg") //Gives the data to the link
        link.click(); //Clicks the 'a' element we created
    }
    
    //We also need to edit the shoot() function
    
    function shoot(){
        var video  = document.getElementById(videoId);
        var output = document.getElementById('output');
        var canvas = capture(video, scaleFactor);
        canvas.onmousedown = function() {
            download(canvas);
        }
    
        snapshots.unshift(canvas);
        output.innerHTML = '' ;
    
        for(var i=0; i<10; i++){
           output.appendChild(snapshots[i]);
    
        }
    }
    

    这样,每当您附加所有快照时,每个画布都会带有自己的 mousedown 事件,因此单击它将返回图像。您甚至可以在此处添加确认框或检查是否单击了鼠标右键。

    问题 2:函数去哪里并不重要,重要的是你调用它们的地方。

    如果您有任何问题,请告诉我!

    【讨论】:

    • 两件事... 首先:我的代码生成了几个图像/帧,我需要选择我需要下载的一个(每个图片/帧一个下载按钮)。您的代码仅获取页面上的第一个画布元素。 其次:我应该在哪里(在我的代码中)粘贴你的函数/sn-ps?
    • 好的!我已将var download = function(canvas) 函数(不是下载所有版本)粘贴到您的示例中所述的“shoot()”函数上方。然后,我像你说的那样通过粘贴canvas.onmousedown... 更改了 shoot 功能。之后,我将var createbutton = function() { 粘贴在var download = function(canvas) 函数下方,注释document.body.appendChild(b); 行并以这种方式调用output.appendChild(createbutton); output.appendChild(createbutton); 下方shoot 函数的output.appendChild(snapshots[i]);,但没有任何反应...我哪里做错了?
    • 让我尝试完全创建您正在尝试执行的脚本。我会将我很快得到的代码粘贴到 jsfiddle。
    • 我仍在努力解决这些错误。出于某种原因,canvas.toDataURL 不想触发onmousedownonclick 事件。通常,这样做的方法是使用canvas.toDataURL 然后下载它,但是它不想工作。我会继续努力。
    • 嗨@Malmadork,有这方面的消息吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    • 2019-04-25
    • 2014-03-21
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多