Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

kCGImageAlphaPremultipliedFirst and kCGImageAlphaFirst

Can you explain to me difference between kCGImageAlphaPremultipliedFirst and kCGImageAlphaFirst? What's mean Premultiplied in practice?

like image 709
Tomasz Szulc Avatar asked Oct 18 '12 08:10

Tomasz Szulc


1 Answers

In short, premultiplied means that the alpha value will also affect the color component values of the pixels when a pixel which is not opaque is represented.

From the Quartz 2D drawing guide:

For bitmaps that have an alpha component, whether the color components are already multiplied by the alpha value. Premultiplied alpha describes a source color whose components are already multiplied by an alpha value. Premultiplying speeds up the rendering of an image by eliminating an extra multiplication operation per color component. For example, in an RGB color space, rendering an image with premultiplied alpha eliminates three multiplication operations (red times alpha, green times alpha, and blue times alpha) for each pixel in the image.

BTW, Pre-Multiplied is likely what the APIs will force you to use because that is Quartz's preference. Fortunately, the conversions aren't terrible (lossy OTOH…).


the shortest way to explain this is in float components, using the range [0...1].

If our RGBA input representation is:

typedef struct t_rgba { float r,g,b,a; } t_rgba;
const t_rgba rgba = { 0.5, 0.5, 0.5, 0.5 };

Then to pre-multiply it:

t_rgba rgba_PreMul = rgba;
rgba_PreMul.r *= rgba_PreMul.a;
rgba_PreMul.g *= rgba_PreMul.a;
rgba_PreMul.b *= rgba_PreMul.a;

Then to de-pre-multiply it:

t_rgba rgba_DePreMul = rgba_PreMul;
if (0.0 < rgba_DePreMul.a && 1.0 > rgba_DePreMul.a) {
  const float ialpha = 1.0/rgba_DePreMul.a;
  rgba_DePreMul.r *= ialpha;
  rgba_DePreMul.g *= ialpha;
  rgba_DePreMul.b *= ialpha;
}

You might want some saturation in there, too.

Now that's the basic form, which can be repurposed to other numeric representations. Note that these conversions are lossy. As well, be careful not to pass premultiplied bitmaps where regular bitmaps are expected, and vice versa.

like image 155
justin Avatar answered Oct 19 '22 04:10

justin