使用 CanvasRenderingContext2D 过滤器保存画布 [英] Saving canvas with CanvasRenderingContext2D filter

查看:27
本文介绍了使用 CanvasRenderingContext2D 过滤器保存画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 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')) {上下文过滤器=模糊(2像素)";}别的 {上下文.过滤器=";}context.drawImage(video, 0, 0);});document.getElementById("download").addEventListener("click", function() {download.href = canvas.toDataURL("image/jpeg");};

.blur {-webkit-过滤器:模糊(3px);-moz-过滤器:模糊(3px);-ms-filter:模糊(3px);-o-过滤器:模糊(3px);过滤器:模糊(3px);}

解决方案

[Edit] : 这个 bug 有 已在 FF52+ 中修复(当前最新的 Nightly)
我给出了答案及其解决方法,以防它在某些时候对某人有所帮助.

<小时>

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

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

然而,它似乎对 svg 过滤器很满意,所以一种解决方法,直到 这个错误 是固定的,是使用 svg 过滤器使用 url(#yourSVGFilter) 值类型.

var img = new Image();var c = document.createElement('canvas');var ctx = c.getContext('2d');document.body.appendChild(c);btn.onclick = 函数(){var i = new Image();i.src = c.toDataURL();document.body.appendChild(i);};img.onload = 函数(){c.width = this.naturalWidth;c.height = this.naturalHeight;//这不会污染画布ctx.filter = 'url(#blurMe)';ctx.drawImage(img, 0, 0);}img.crossOrigin = '匿名';img.src = 'https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png';

<filter id="blurMe"><feGaussianBlur in="SourceGraphic" stdDeviation="2"/></过滤器></svg><button id="btn">调用 toDataURL()</button><br>

(还有一个 fiddle 出于好奇而重现了这个问题)

I have the problem with saving photo with CanvasRenderingContext2D.filter. When I connect to video and try to take a shot without any filters, it saves normally. However, after adding some filters to canvas, it is saving as HTM file or return previous photo without filters if it was made. The weird is, that while downloading that screenshot manually by clicking on it, it does have own toDataUrl, downloads normally and contains filter but while saving it using toDataUrl, it still doesn't see that picture. What should I do to save photos with these filters?

Here is the piece of my code:

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>

解决方案

[Edit] : This bug has been fixed in FF52+ (current latest Nightly)
I let the answer and its workaround in case it helps someone some time.


This seems to be a bug in Firefox with filter-functions. Chrome 54 seems to handle it just right.

When a filter-function is passed as the value of ctx.filter, FF does taint the canvas, making all export methods unavailable (toDataURL included).

However, it seems pretty happy with svg filters, so one workaround, until this bug is fixed, is to use an svg filter along with the url(#yourSVGFilter) value type.

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>

(And a fiddle that reproduces the problem for curious)

这篇关于使用 CanvasRenderingContext2D 过滤器保存画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆