Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
332 views
Welcome To Ask or Share your Answers For Others

1 Answer

[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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...