- 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