- From: Cameron McCormack <cam@mcc.id.au>
- Date: Fri, 18 Feb 2011 16:24:08 +1300
- To: public-svg-wg@w3.org
I am reviewing my test painting-render-02-b.svg for correctness. The
test involves alpha compositing when color-interpolation="linearRGB".
I will run through a worked example here, and hopefully someone can tell
me if I am doing it right.
Let’s perform alpha compositing where the background pixel is (0,0,0,1),
opaque black, and the foreground pixel to be composited into the
background is (1,1,1,0.5), half opaque white. (I’m using component
values in the range [0, 1].)
For the sRGB ↔ linearRGB conversions I’m using the formulae on
http://en.wikipedia.org/wiki/SRGB#Specification_of_the_transformation:
R_s = R_linear ≤ 0.0031308 ? 12.92 * R_linear
: min(1.055 * pow(R_linear, 1 / 2.4), 1)
G_s = G_linear ≤ 0.0031308 ? 12.92 * G_linear
: min(1.055 * pow(G_linear, 1 / 2.4), 1)
B_s = B_linear ≤ 0.0031308 ? 12.92 * B_linear
: min(1.055 * pow(B_linear, 1 / 2.4), 1)
A_s = A_linear
and
R_linear = R_s ≤ 0.04045 ? R_s / 12.92
: pow((R_s + 0.055) / 1.055, 2.4)
G_linear = G_s ≤ 0.04045 ? R_s / 12.92
: pow((G_s + 0.055) / 1.055, 2.4)
B_linear = B_s ≤ 0.04045 ? B_s / 12.92
: pow((B_s + 0.055) / 1.055, 2.4)
A_linear = A_s
and for the compositing itself the formulae at
http://www.w3.org/TR/SVG/masking.html#SimpleAlphaBlending:
R_result = min((1 - A_fg) * R_bg + R_fg, 1)
G_result = min((1 - A_fg) * G_bg + G_fg, 1)
B_result = min((1 - A_fg) * B_bg + B_fg, 1)
A_result = 1 - (1 - A_fg) * (1 - A_bg)
For the unpremultiplied ↔ premultiplied alpha conversions I’m doing
R_pre = R * A
G_pre = G * A
B_pre = B * A
A_pre = A
and
R = R_pre / A
G = R_pre / A
B = R_pre / A
A = A_pre
So we start with:
bg = (0, 0, 0, 1)
fg = (1, 1, 1, 0.5)
Convert them to linearRGB space:
bg_linear = (0, 0, 0, 1)
fg_linear = (1, 1, 1, 0.5) i.e., the same values
Since the alpha compositing is done with premultiplied colours, we
multiply the alpha in:
bg_linear_pre = (0, 0, 0, 1)
fg_linear_pre = (0.5, 0.5, 0.5, 0.5)
Do the alpha blending:
result_linear_pre = (0.5, 0.5, 0.5, 1)
Unpremultiply:
result_linear = (0.5, 0.5, 0.5, 1)
Convert to sRGB:
result = (0.790357, 0.790357, 0.790357, 1)
I think in this particular example, the order of the colour space
conversion and the alpha multiplication/division doesn’t matter, since
you get the same result. Is that true in general, though?
Is my method above correct?
--
Cameron McCormack ≝ http://mcc.id.au/
Received on Friday, 18 February 2011 03:24:49 UTC