画布

时间:2017-03-11 18:09:58

标签: javascript html5 canvas svg svg-filters

我正在使用canvas中的SVG过滤器实现,但我在复合算术运算符方面存在两个问题。

此运算符的实现基于W3C specification和firefox9源代码。

这是我的过滤器和代码的代码svg例如:Fiddle complete code

var k1Scaled = options.k1 / 255;
var k4Scaled = options.k4 * 255;
for(v=0; v<datas.length; v+=4) {
   r = datasB1[v+0];
   g = datasB1[v+1];
   b = datasB1[v+2];
   a = datasB1[v+3];
   r1 = datasB2[v+0];
   g1 = datasB2[v+1];
   b1 = datasB2[v+2];
   a1 = datasB2[v+3];
   //if (a === 0 && a1 === 0) continue;
   vR = k1Scaled * r1 * r + options.k2 * r + options.k3 * r1 + k4Scaled;
   vG = k1Scaled * g1 * g + options.k2 * g + options.k3 * g1 + k4Scaled;
   vB = k1Scaled * b1 * b + options.k2 * b + options.k3 * b1 + k4Scaled;
   vA = k1Scaled * a1 * a + options.k2 * a + options.k3 * a1 + k4Scaled;
   datas[v+0] = Math.min(Math.max(0, ~~vR), 255);
   datas[v+1] = Math.min(Math.max(0, ~~vG), 255);
   datas[v+2] = Math.min(Math.max(0, ~~vB), 255);
   datas[v+3] = Math.min(Math.max(0, ~~vA), 255);
}

我的第一个问题:由于公式,我在透明像素上有银色,如果我在透明像素上分解公式,结果是:

result = k1 * i1 * i2 + k2 * i1 + k3 * i2 + k4

其中k1 = 0.5 / 255 = 0.0019,i1 = 0,i2 = 0,k2 = 0.5,k3 = 0.5,k4 = 0.5 * 255 = 127

结果= 0.0019 * 0 * 0 + 0.5 * 0 + 0.5 * 0 + 127 = 127 =&gt; rgba上的白银

我的第二个问题:我的结果比svg例子更不透明,我想webbrowser预先乘以rgba结果,但我尝试了这个但没有结果。

我不能在画布上使用svg过滤器,我需要纯粹的javascript / canvas实现。

如果您有任何想法或解决方案,请提前感谢。

卡锐。

1 个答案:

答案 0 :(得分:0)

Here the solution

this._arithmetic = function(options, ctx) {
  var b1, ctxB1, ctxB2, w, h, x, y, v, imgDatas, datas, imgDatasB1, datasB1, imgDatasB2, datasB2;
  b1 = document.createElement("canvas");
  ctxB1 = b1.getContext("2d");
  ctxB1.resize(this.width,this.height);
  ctxB1.drawImage(options.in.source, options.in.options.x, options.in.options.y, options.in.options.width, options.in.options.height);
  imgDatasB1 = ctxB1.getImageData(0,0,this.width,this.height);
  this.premultiply(imgDatasB1);
  datasB1 = imgDatasB1.data;

  b2 = document.createElement("canvas");
  ctxB2 = b2.getContext("2d");
  ctxB2.resize(this.width,this.height);
  ctxB2.drawImage(options.in2.source, options.in2.options.x, options.in2.options.y, options.in2.options.width, options.in2.options.height);
  ctx.resize(this.width,this.height);
  ctx.drawImage(b2, 0, 0);
  imgDatas = ctx.getImageData(0,0,this.width,this.height);
  this.premultiply(imgDatas);
  datas = imgDatas.data;
  var k1Scaled = options.k1 / 255;
  var k4Scaled = options.k4 * 255;
  var vR,vG,vB,vA,r,g,b,a,r1,g1,b1,a1;
  for(v = 0;v < datas.length;v += 4) {
    r = datasB1[v + 0];
    g = datasB1[v + 1];
    b = datasB1[v + 2];
    a = datasB1[v + 3];

    r1 = datas[v + 0];
    g1 = datas[v + 1];
    b1 = datas[v + 2];
    a1 = datas[v + 3];

    vR = k1Scaled * r1 * r + options.k2 * r + options.k3 * r1 + k4Scaled;
    vG = k1Scaled * g1 * g + options.k2 * g + options.k3 * g1 + k4Scaled;
    vB = k1Scaled * b1 * b + options.k2 * b + options.k3 * b1 + k4Scaled;
    vA = k1Scaled * a1 * a + options.k2 * a + options.k3 * a1 + k4Scaled;

    vR = vR < 0 ? 0 : vR > 255 ? 255 : vR;
    vG = vG < 0 ? 0 : vG > 255 ? 255 : vG;
    vB = vB < 0 ? 0 : vB > 255 ? 255 : vB;
    vA = vA < 0 ? 0 : vA > 255 ? 255 : vA;

    datas[v + 0] = vR;
    datas[v + 1] = vG;
    datas[v + 2] = vB;
    datas[v + 3] = vA;
  }
  this.unPremultiply(imgDatas);
  ctx.putImageData(imgDatas,0,0);
};

预乘+ unPremultiply函数的代码在小提琴链接中。