function darker(src, dst, globalAlpha)
{
var w,h;
if(src.width > dst.width)
{
w = src.width;
}
else
{
w = dst.width;
}
if(src.height > dst.height)
{
h = src.height;
}
else
{
h = dst.height;
}
var ctx1 = src.getContext("2d");
var canvas = document.createElement("canvas");
canvas.setAttribute("width", w);
canvas.setAttribute("height", h);
ctx2 = canvas.getContext("2d");
ctx2.drawImage(src, 0, 0);
var canvas2 = document.createElement("canvas");
canvas2.setAttribute("width", w);
canvas2.setAttribute("height", h);
ctx3 = canvas2.getContext("2d");
ctx3.drawImage(dst, 0, 0);
var result = ctx2.getImageData(0, 0, w, h);
var blend = ctx3.getImageData(0, 0, w, h);
var alpha;
for(var data = result.data, blend = blend.data, i = 0 ; i < data.length ; i+=4)
{
if(typeof globalAlpha !== "undefined") gA = globalAlpha * 1;
else gA = 1;
alpha = blend[i+3] * gA;
alpha = alpha / 255;
if(data[i] == 0 && data[i+1] == 0 && data[i+2] == 0 && data[i+3] == 0)
{
data[i] = blend[i], data[i+1] = blend[i+1], data[i+2] = blend[i+2], data[i+3] = alpha * 255;
}
else
{
data[i] = ((data[i]) * (1 - alpha) + -blend[i] * (alpha));
data[i+1] = ((data[i+1]) * (1 - alpha) + -blend[i+1] * (alpha));
data[i+2] = ((data[i+2]) * (1 - alpha) + -blend[i+2] * (alpha));
data[i+3] = 255;
}
}
ctx1.putImageData(result, 0, 0);
return src;
}
背景色が白以外の場合に動作がおかしかったのと、
globalAlphaへの対応を追加。
いろいろ計算式をいじっていてこれで動いたけど、
なぜこの計算式なのかは不明。
ChromeとSafariの実装にあわせたからこの式になったけど、
Firefoxと同じ結果になる式のほうが論理的に正しいのかもしれない。