我正在使用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实现。
如果您有任何想法或解决方案,请提前感谢。
卡锐。
答案 0 :(得分:0)
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函数的代码在小提琴链接中。