我正在设计一款类似于Photoshop的基于HTML5 Canvas元素的Web应用程序。该程序在没有使用混合模式时运行良好且速度很快。但是,一旦加入混合模式,程序就会变得缓慢。我通过将每个画布元素合并成一个,并从底部画布开始使用正确的混合模式组合每个画布的每个像素来实现混合模式。
for (int i=0; i<width*height*4; i+=4) {
var base = [layer[0][i],layer[0][i+1],layer[0][i+2],layer[0][i+3]];
var nextLayerPixel = [layer[1][i],layer[1][i+1],layer[1][i+2],layer[1][i+3]];
//Apply first blend between first and second layer
basePixel = blend(base,nextLayerPixel);
for(int j=0;j+1 != layer.length;j++){
//Apply subsequent blends here to basePixel
nextLayerPixel = [layer[j+1][i],layer[j+1][i+1],layer[j+1][i+2],layer[j+1][i+3]];
basePixel = blend(basePixel,nextLayerPixel);
}
pixels[i] = base[0];
pixels[i+1] = base[1];
pixels[i+2] = base[2];
pixels[i+3] = base[3];
}
canvas.getContext('2d').putImageData(imgData,x,y);
使用IT调用不同的混合模式。我的“正常”混合模式如下:
var blend = function(base,blend) {
var fgAlpha = blend[3]/255;
var bgAlpha = (1-blend[3]/255)*base[3]/255;
blend[0] = (blend[0]*fgAlpha+base[0]*bgAlpha);
blend[1] = (blend[1]*fgAlpha+base[1]*bgAlpha);
blend[2] = (blend[2]*fgAlpha+base[2]*bgAlpha);
blend[3] = ((blend[3]/255+base[3])-(blend[3]/255*base[3]))*255;
return blend;
}
我的Chrome测试结果(在测试的浏览器中表现最佳)是在一个 620x385(238,700 像素)的画布上混合三层,大约需要 400ms。
这只是一个非常小的实现,因为大多数项目的规模都会更大,并且包含更多的图层,这将使这种方法下的执行时间急剧增加。
我想知道是否有更快的方法来结合两个带有混合模式的画布上下文,而无需逐个像素地处理。
nextLayerPixel
是什么?你如何创建它,为什么要在blend
函数(第二个参数)中更改它? - Bergi