Сохранение холста с помощью фильтра 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')) {
                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>

1 ответ

[Редактировать]: эта ошибка была исправлена в FF52 + (текущая последняя Ночная)
Я даю ответ и его обходной путь на случай, если он кому-нибудь поможет.


Кажется, это ошибка в 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 = 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>

скрипка, которая воспроизводит проблему для любопытных)

Другие вопросы по тегам