# Alpha compositing

Alpha compositing (or simply *compositing*) is combining multiple (possibly partially transparent) layers of image data into a single image. If you have ever used Photoshop or GIMP, compositing is how all the layers are combined into a final image that can be displayed on screen.

The image data is assumed to be saved in the form of a grid of pixels, so that compositing can be done per pixel. In this post I will derive the composition equation, which describes how to compose one pixel onto another.

## Notation

I will write a pixel $P$ as

$P=((R,G,B),α)$$R$, $G$, $B$, and $α$ are values in $[0,1]$. The RGB components should correspond to the color of the pixel, expressed in a linear color space. This is important: as I wrote before, the default color space sRGB is not linear, so it needs to be converted! The alpha component corresponds to the opacity of the pixel, if $α=0$ the pixel is fully transparent (e.g. invisible) and if $α=1$ it is fully opaque (e.g. if it is composited on top of another pixel, that other pixel will not be visibly anymore).

I will often write $C=(R,G,B)$ because in the equations we don’t need to distinguish between the individual RGB components. The composition of a pixel $X$ on top of a pixel $Y$ is denoted as $X→Y$, and the RGB and alpha components of a pixel $X$ are denoted as $C_{X}$ and $α_{X}$.

## The compositing equation

First, we consider the case where we composite a pixel $X$ on a pixel $Y$ which is opaque (so $α_{Y}=1$). If $α_{X}=1$ we expect the resulting color to be equal to $C_{X}$, and if $α_{X}=0$ we expect the resulting color to be equal to $C_{Y}$. Assuming that the transition is linear we derive

$α_{X→Y}C_{X→Y} =1=α_{X}C_{X}+(1−α_{X})C_{Y} $The generic case is a bit more complicated. We start with the alpha component. Physically, transparent object lets a certain fraction of light pass through it. If we have two objects on top of each other, and the first object lets a fraction $(1−α_{X})$ of light through, and the second lets a fraction $(1−α_{Y})$ of light through, we expect a fraction of $(1−α_{X})(1−α_{Y})$ to go through both objects. Applying the same principles, we expect that $1−α_{X→Y}=(1−α_{X})(1−α_{Y})$. More elegantly put,

$α_{X→Y}=α_{X}+α_{Y}−α_{X}α_{Y}$For the RGB components it’s not clear where to start. It turns out to be informative to evaluate the RGB components of $X→Y→Z$ where $Z$ is opaque. We can evaluate this as $(X→Y)→Z$ or as $X→(Y→Z)$. We find

$C_{(X→Y)→Z}=α_{X→Y}C_{X→Y}+(1−α_{X→Y})C_{Z}$and

$C_{X→(Y→Z)} =α_{X}C_{X}+(1−α_{X})C_{Y→Z}=α_{X}C_{X}+(1−α_{X})(α_{Y}C_{Y}+(1−α_{Y})C_{Z}) $Since there really is just one result of compositing three pixels, we expect that both orders of evaluation give the same result (in mathspeak, the composition operator $→$ is [associative)[https://en.wikipedia.org/wiki/Associative_property]). That is, $(X→Y)→Z=X→(Y→Z)$.

Now, setting $C_{(X→Y)→Z}=C_{X→(Y→Z)}$ and simplifying a bit using the formula for $α_{X→Y}$ we found before, we find

$α_{X→Y}C_{X→Y}=α_{X}C_{X}+(1−α_{X})α_{Y}C_{Y}$This finally gives us the full, generic composition equation

$α_{X→Y}C_{X→Y} =α_{X}+α_{Y}−α_{X}α_{Y}=α_{X→Y}α_{X}C_{X}+(1−α_{X})α_{Y}C_{Y} $## Premultiplied alpha

It is worth noting that the composition equation we derived in the last section contains a division. This is not ideal as divisions are very expensive to compute. The astute reader might have noticed that for any pixel we really only use the product of the RGB components and the alpha component. So instead of storing the RGB components, we can store the product of the RGB components and the alpha component (we still need to store the alpha component itself since it is needed in the composition equation).

This technique is known as **premultiplied alpha** or **associated alpha** (and not using it is sometimes called **straight alpha** or **unassociated alpha**). It makes computing compositions much nicer; instead of computing $C_{X→Y}$ we compute $α_{X→Y}C_{X→Y}$ and the composition equation becomes

It is worth noting that using premultiplied alpha throws away information in the color components for which $α=1$. So you should never store images with premultiplied alpha if you intend on making changes to the alpha channel. So in the context of a project, it’s probably best to have images with straight alpha under version control, and then convert them to premultiplied alpha as a build step. Alternatively, your application can convert to premultiplied alpha when it imports images (this is also a good place to convert to a linear color space, if it is necessary).

## Sources

[1] https://ciechanow.ski/alpha-compositing/

[2] https://en.wikipedia.org/wiki/Alpha_compositing