I am creating a Photoshop-style web application that runs on an HTML5 Canvas element. The program works well and very quickly, until I add mixed modes to it. I get blending modes by combining each canvas element into one and combining every pixel from each canvas using the correct blending modes starting from the bottom canvas.
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]];
basePixel = blend(base,nextLayerPixel);
for(int j=0;j+1 != layer.length;j++){
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);
With this call blend for different blending modes. My βnormalβ blending mode is as follows:
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;
}
The results of my tests in Chrome (giving some of the best tested browsers) were about 400 ms, mixing the three layers together on 620x385 canvas (238,700 pixels).
, , .
, canvas , .