【问题标题】:Saving canvas with CanvasRenderingContext2D filter使用 CanvasRenderingContext2D 过滤器保存画布
【发布时间】:2017-02-28 10:24:49
【问题描述】:

我在使用 CanvasRenderingContext2D.filter 保存照片时遇到问题。当我连接到视频并尝试在没有任何滤镜的情况下拍摄时,它会正常保存。但是,在画布上添加了一些过滤器后,它会保存为 HTM 文件或返回以前没有过滤器的照片(如果已制作)。奇怪的是,当通过单击手动下载该屏幕截图时,它确实有自己的 toDataUrl,正常下载并包含过滤器,但在使用 toDataUrl 保存时,它仍然看不到该图片。 我应该怎么做才能使用这些滤镜保存照片?

这是我的一段代码:

var canvas = document.getElementById('canvas');       
var context = canvas.getContext('2d');  
var video = document.getElementById("video");

document.getElementById("snapshot").addEventListener("click", function() {
            if ($('video').hasClass('blur')) {
                context.filter ="blur(2px)";
            }
            else {
            context.filter= "";
            }
              context.drawImage(video, 0, 0);
      });
      
document.getElementById("download").addEventListener("click", function() {
              download.href = canvas.toDataURL("image/jpeg");
              };
.blur {
  -webkit-filter: blur(3px);
     -moz-filter: blur(3px);
      -ms-filter: blur(3px);
       -o-filter: blur(3px);
          filter: blur(3px);
}
<video id="video" autoplay></video>
<canvas id="canvas"></canvas>
<button id="download" download="picture" href=""></button>

【问题讨论】:

    标签: javascript html canvas html5-canvas todataurl


    【解决方案1】:

    [编辑]:这个错误在 FF52+ 中有 been fixed(当前最新的 Nightly)
    我让答案及其解决方法,以防它在一段时间内对某人有所帮助。


    这似乎是 Firefox 中带有过滤器功能的错误。 Chrome 54 似乎处理得恰到好处。

    当过滤函数作为ctx.filter 的值传递时,FF 会污染画布,使所有导出方法不可用(包括toDataURL)。

    但是,svg 过滤器似乎很满意,因此在修复this bug 之前,一种解决方法是使用svg filterurl(#yourSVGFilter) 值类型。

    var img = new Image();
    var c = document.createElement('canvas');
    var ctx = c.getContext('2d');
    document.body.appendChild(c);
    
    btn.onclick = function() {
      var i = new Image();
      i.src = c.toDataURL();
      document.body.appendChild(i);
    };
    
    img.onload = function() {
      c.width = this.naturalWidth;
      c.height = this.naturalHeight;
      // this doesn't taint the canvas
      ctx.filter = 'url(#blurMe)';
    
      ctx.drawImage(img, 0, 0);
    }
    
    img.crossOrigin = 'anonymous';
    img.src = 'https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png';
    <svg width="0" height="0">
      <filter id="blurMe">
        <feGaussianBlur in="SourceGraphic" stdDeviation="2" />
      </filter>
    </svg>
    
    <button id="btn">call toDataURL()</button><br>

    (还有一个 fiddle 会重现问题以供好奇)

    【讨论】:

      猜你喜欢
      • 2015-08-05
      • 1970-01-01
      • 2017-10-10
      • 1970-01-01
      • 2015-11-16
      相关资源
      最近更新 更多