iOS Drawing: Practical UIKit Solutions (2014)
A. Blend Modes
Blend modes tell a context how to apply new content to itself. They determine how pixel data is digitally blended. For example, the default blend mode simply adds new material on top of whatever data is already in the context. You can do much more, however. Blend modes allow you to emulate Photoshop-style layer effects. You’ll find familiar operations like multiply, color dodge, hard light, and difference among the available modes.
Listing A-1 demonstrates how you set a context’s blending mode. You call CGContextSetBlendMode() with the current context, specifying which mode you wish to use. These modes, which are enumerated as CGBlendMode, are detailed in Table A-1.
Listing A-1 Applying a Blend Mode
// Draw the first shape
// Set the blending mode
// Draw the second shape
Table A-1 Blend Modes
Listing A-1 generated the first of each figure pair in Table A-1. This listing draws a green circle to the context and then sets a blend mode. That blend mode applies to the purple circle, which is drawn next. The result of that operation depends on the blend mode that was specified. The second image in each pair draws a circle over a photograph. This supplies a more nuanced expression of each blend mode. It uses the same approach as Listing A-1 but replaces the green circle with an image-drawing command.
One of the reasons there are so many blend modes listed in Table A-1 is that the first half of the list is older modes. The normal (kCGBlendModeNormal) through luminosity (kCGBlendModeLuminosity) modes first appeared in OS X Tiger. The Porter-Duff blend modes that follow didn’t debut until OS X Leopard. These consist of the clear (kCGBlendModeClear) through plus-lighter (kCGBlendModePlusLighter) blends. Every mode in Table A-1 is available in iOS.
The Porter-Duff collection is annotated with mathematical equations, which refer to R, S, and D. The result (R) of any blend operation represents the result of blending the source pixel values (S), the source alpha levels (Sa), the destination pixel values (D), and the destination alpha levels (Da).
Apple writes in the Quartz documentation:
Note that the Porter-Duff blend modes are not necessarily supported in every context. In particular, they are only guaranteed to work in bitmap-based contexts, such as those created by CGBitmapContextCreate. It is your responsibility to make sure that they do what you want when you use them in a CGContext.... Note that the Porter-Duff “XOR” mode is only titularly related to the classical bitmap XOR operation which is unsupported by CoreGraphics.
For example, here is the equation for the normal blend mode:
R = (Sa × S) + ((1 – Sa) × D)
The result consists of the source pixels multiplied by their alpha level, added to the remaining alpha capacity, multiplied by destination pixels.
If the source is entirely opaque in normal blending, the result entirely represents the source color. If the source is half transparent, the result is created half from the source and half from whatever material has already been added to the context at that point.
Each blend mode, regardless of when it was added to iOS or OS X or how it is documented, creates a rule that expresses the relationship between the source material (the pixels being applied) and the destination (the pixels already stored to the context).