【问题标题】:HTML5 save Canvas image every few secondsHTML5 每隔几秒保存一次 Canvas 图像
【发布时间】:2017-08-24 01:07:17
【问题描述】:

如何每隔几秒钟将画布图像保存到文件夹。

我有一个基本的画布绘图功能和一个下载功能来保存图像,如下所示:

<canvas></canvas>

var link = document.createElement('a');
    link.innerHTML = 'download image';
link.addEventListener('click', function(ev) {
    link.href = canvas.toDataURL();
    link.download = "mypainting.png";
}, false);
document.body.appendChild(link);

我想实现一个名为开始/停止的按钮。

如果用户单击该按钮,我想每秒保存一次画布图像。

每张图片都应保存为一个新文件。

这怎么可能? 有可能吗?

【问题讨论】:

  • 保存是指每秒更新同一个文件,还是另存为新文件?
  • @Ivar 它总是一个新文件
  • 为什么要每隔几秒保存一次?它是作为撤消历史记录还是什么?预期用途会极大地影响解决方案。
  • @EmilS.Jørgensen 另一个应用程序需要每秒获取这些图像以向用户展示......我不能多说
  • 那你恐怕不知所措了。浏览器不允许在没有用户交互的情况下自动下载到特定文件夹。这是浏览器的安全问题,防止站点将病毒直接放入System32 等。您可以每隔几秒钟提示用户下载一次,但这将是糟糕的用户体验。您是否可以使用一些服务器端代码将图像放在需要去的地方?如果您的服务器可以访问相关文件夹,那么它可以将文件放在需要去的地方。

标签: javascript html canvas


【解决方案1】:

是的,这是可能的。浏览器会询问用户是否允许下载多个文件。只有当用户点击确认他/她要允许多个文件下载时,它才会下载多个图像。

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

function doCanvas() {
    ctx.fillStyle = '#f90';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = '#fff';
    ctx.font = '30px sans-serif';
    ctx.fillText('Code Project', 10, canvas.height / 2 - 15);
    ctx.font = '13px sans-serif';
    ctx.fillText('Click start to download images', 15, canvas.height / 2 + 35);
}

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

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

doCanvas();

$( document ).ready(function() {
  $('#start').on('click', function() {
    if( confirm('This will continue download image every 2 second, do you want to proceed?') ) {
      setInterval(function() {
          $('#download')[0].click();
        }, 2000);
    }
  });
});
body {
  background-color:#555557;
  padding:0;
  margin:0;
  overflow:hidden;
  font-family:sans-serif;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
canvas {
  border:1px solid #000;
  float:left;
  clear:both;
}
#download {
  float:left;
  cursor:pointer;
  color:#ccc;
  padding:3px;
}
#download:hover {
  color:#fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas width="250" height="150" id="canvas">Sorry, no canvas available</canvas>
<p>Make sure you have not blocked multiple file downloads.</p>
<a id="download"> </a>
<button id="start">Start</button>

SOURCE

【讨论】:

  • 这只会保存一次图像
  • @Kaiido 好的,在用户每 2 秒下载一次图像之前发送确认信息。我猜问题解决了
【解决方案2】:

我使用这个脚本。

    function saveImageAs(canvas, filename, type, quality){      // No IE <10 support. Chrome URL bug for very large images may crash
        var anchorElement, event, blob;
        type = type ? "png" : type;

        // for IE >= 10
        if(canvas.msToBlob !== undefined && navigator.msSaveBlob !== undefined){ 
           blob = canvas.msToBlob(); 
           navigator.msSaveBlob(blob, filename + "." + type); 
           return;
        }
        anchorElement = document.createElement('a');    // Create a download link
        if(type.toLowerCase() === "jpg" || type.toLowerCase() === "jpeg"){
            quality = quality ? quality : 0.9;
            anchorElement.href = canvas.toDataURL("image/jpeg",quality);         // attach the image data URL
        }else{                
            anchorElement.href = canvas.toDataURL();         // attach the image data URL
        }
        // check for download attribute
        if ( anchorElement.download !== undefined ) {
            anchorElement.download = filename + "." + type; // set the download filename
            if (typeof MouseEvent === "function") {     // does the browser support the object MouseEvent
                event = new MouseEvent( "click", {view  : window, bubbles: true,cancelable : true} );
                anchorElement.dispatchEvent(event); // simulate a click on the download link.
            } else
            if (anchorElement.fireEvent) {          // if no MouseEvent object try fireEvent 
                anchorElement.fireEvent("onclick");
            }
        }
    }

然后是一个简单的下载计时器。

var timeoutHandle;
function startDownloads(){
    saveImageAs(canvas,"snap.jpg","jpeg");
    timeoutHandle = setTimeout(startDownloads,2000);
}
function stopDownloads(){
    clearTimeout(timeoutHandle);
}

文件的放置位置和名称由客户端决定。无法保证文件最终会在客户端的驱动器上,也无法知道下载是否已完成。

注意很遗憾原始答案已被删除。不是每个人都会同意方法,但这并不意味着方法是错误的。 “将不起作用”仅适用于不良代码,不适用于客户偏好。还是我们都应该删除答案,因为某些用户阻止了 Javascript,因此任何 javascript 答案都不起作用..

很高兴看到原来的答案。?

【讨论】:

  • 所以我会把这个“quote note”交给我。发生这种情况时,请选择评论,而不是将其包含在您的答案中,这与那里无关。当我发表此评论指出人们不应运行此 sn-p 时,每隔 1 秒就会出现一个警报以及“另存为”弹出窗口。这意味着一个无限循环,除非您足够快地关闭此警报,否则请避免弹出窗口并单击hide snippet 链接。然后,不,它不会工作。这并不是因为一个浏览器默认在我说是一次之后总是信任该网站它适用于所有浏览器...
  • ...在市场上。 “未经他的同意,我们不能在用户机器上保存” 仍然是默认行为。更不用说最初的想法是可怕的(如果我把我的电脑留在这个页面上几个小时而没有注意到它正在填满我的硬盘呢?),但是让它成为 49% 的市场的可怕 UX 会毁了你的网站。所以说“是的,有可能” 是错误的,不显示关于巨大警告 的注释也是错误的。
  • @Kaiido 我完全理解,你是对的,用户将运行 sn-p,并且没有关于他们将进入什么的警报。
  • 为什么这个答案是-1?有人解释一下。 @Blindman67 赞成.. 尊重 :)
  • @roundAbout 谁知道呢!投票的原因有时与答案或问题的内容不一致。顺便说一句,欢迎来到 SO,我很高兴您恢复了答案,这个问题引起了高于平均水平的关注,您的回答是如何使用 jquery 实现 OP 需求的一个很好的例子。多样性使答案保持新鲜,吸引知识渊博的新贡献者是多样性的重要组成部分,因此我尽量鼓励像您这样的新用户参与进来,不要因不同的观点而气馁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多