Сохранение холста с помощью фильтра 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>
(И скрипка, которая воспроизводит проблему для любопытных)