Single-pixel Width Outlines with Anti-Aliasing

October 16, 2012

Good old XOR drawing can be anti-aliased in order to better meet today’s aesthetic standards. In GIMP terms:

Duplicate the layer, invert it and simply perform the outline drawing on the layer mask.


(created with a slightly more elaborate scheme, see below)

What’s wrong with the current 3-line outline style?

Ideally, outlines should be much thinner than the desired resolution of the adjustment. Note how the tick marks of a ruler are much thinner in dimension than the resolution of the ruler. Roughly 1/10 of a millimeter thin marks for a ruler with 1mm resolution.

Now one could rely on the trend towards higher screen DPIs which will gracefully let the 3-line outline appear accurate enough in near future. Fair enough — but then a new problem will show up: when the three lines can no longer be visually distinguished, they will appear as an overlay of a single gray line. Which in turn does not provide enough contrast in all situations.

You may simulate the effect of high DPIs by stepping back while looking at the following test image. One of the vertical outlines will blend into the background:

(click to enlarge thumbnail)

Which color should the single-pixel outline have?

The ideal outline contrasts both the surrounding pixels and the underlying pixels in any situation. But which color gives the best contrast? The W3C recommendations for contrast between text and its background [1] seem close enough here — what is good for reading performance can only be good for outline recognition.

It turns out that pure black and white pixels yield the highest contrast ratios. Brightness contrast beats color contrast. Which nicely matches the GUI attitude to let the colorful pixels to the user, not to the application.

In summary, this gives the following steps:

  1. Calculate luminance of underlying pixels
  2. Threshold to black and white
  3. Invert
  4. Mask by desired outline

(Regrettably, contrast to surrounding pixels is not taken into account here)

What’s wrong with these black’n’white outlines?

The harsh contrast edges can be distracting. This problem apppears most prominently when moving an outline, in particular over smooth image regions which are just about as bright as the threshold. You may try this Flash demo:

or try moving the layer mask of the upper layer of the following XCF:

Still way to go, but it’s a start…

see also


layer mode icons

October 1, 2009

some decoration for the layer mode menu:

What these funny colorful pixels are about

why this particular grouping was chosen:

… and a preliminary patch to try this live…

Blend Modes Examined 1: Brightness&Contrast

September 27, 2009

Graphics applications are hosting a zoo of blend modes to offer more or less fine-grained control over certain aspects of a composite image. Two of these aspects, brightness and contrast, are studied in the following by means of suitable diagrams.

Starting with brightness, the following table gives a comparison of various blend modes:
comparison of blend modes - brightness effects
html-version (zipped), also taking different opacity values into account

blending basics


Before delving into the different diagram types, a word about how two layers are blended into each other: for each pixel, the result value gets calculated from the base layer value a and the blend layer value b. For RGB blend modes — which are solely considered here– these calculations are carried out separately for each of the R,G,B values using a single function f(a,b). Thus, one such function is sufficient to fully describe a RGB blend mode.

Brightness Value

This diagram shows the resulting value for all possible combinations of base and blend layer values. For the ‘multiply’ mode f(a,b) = ab, it looks like this:
multiply mode: brightness value diagram
Contours are enhanced by using only a few shades of gray to display the result value. In general, blend modes have smooth graphs without steps.

commutative modes

If swapping the input layers doesn’t change the result, a blend mode is said to be commutative. This shows up as the brightness plot being symmetrical with regard to the first diagonal, which is displayed as a dashed green line in the diagram above. Obviously, ‘multiply’ is a commutative blend mode.

reciprocal pairs

For a few non-commutative blend modes, swapping the input layers leads to another well-known blend mode. Such reciprocal pairs have the same brightness graph, just mirrored along the first diagonal. For example, ‘overlay’ is the reciprocal mode of ‘hardlight’ (or reverse mode, if you prefer):

brightness value diagrams for hardlight and overlay

inverting modes

The majority of blend modes features increasing brightness values towards the top or the right of their brightness diagram, but never towards the opposite directions. In the latter case, solarization effects are introduced and the corresponding modes are called inverting (or comparative) modes. For example:
examples of inverting and non-inverting modes; brightness diagrams
More on that later, when contrast gets examined.

Brightness Difference

This type of diagram depicts how the image’s brightness changes when a new layer gets blended in. The difference between the result and the base layer gets plotted using a color code. For the ‘multiply’ mode:

multiply mode: brightness difference diagram

It can be seen that the ‘multiply’ mode qualifies for the group of darkening blend modes: there are only greenish and bluish colors present in the plot, which means that the result is always the same as or darker than the base layer value.

With decreasing brightness of the blend layer, the darkening effect gets stronger. The strongest darkening takes place where the blend layer is dark and the base layer is bright, that is in the lower right corner of the plot. Of course, when the base layer itself is already dark (the leftmost region of the diagram), no further darkening is possible. For comparison, the ‘black’ mode exemplifies the maximum amount of darkening possible:

brightness diffs: black vs. multiply mode

neutral value

A horizontal line of green indicates the neutral value for the blend value b: no changes are done to the image regardless of the base layer’s value a. For the ‘multiply’ mode, the neutral value is 1, for ‘overlay’ and ‘dodge’ 0.5 and 0, respectively:
neutral values; examples of brightness diff diagrams
In contrast, the ‘normal’ mode doesn’t feature a neutral value — the image remains unchanged only where the blend layer is identical to the base layer (that is where a=b).

complementary modes

Inverting both input layers as well as the result creates the complementary blend mode. Graphically, this shows up as a rotation by 180 degrees and swapping of red by blue, like flipping the color scheme. Two complementary pairs for example:

examples of complementary modes; brightness diffs

The math:

\mathrm{complement}\left\{f(a,b)\right\} = \overline{f(\overline{a}, \overline{b})} = 1-f(1-a,1-b)

II. Contrast

Three more diagram types characterize the contrast effects of blend modes:
comparison of blend modes - contrast effects
html-version (zipped)


When the blend layer has a constant value, blending becomes the same operation as applying a curve to the base layer. For example, adding a black blend layer (b=0) using the ‘softlight’ mode has the same effect as a gamma correction with \gamma=2: in both cases the result value is f(a) = a^2.

For each possible value of b, distinct curves get applied. So for 8bit-images, a blend mode can alternatively be described as a set of 256 curves. A few of these curves of the ‘multiply’ blend mode:

multiply mode: curves in context with brightness plot

Each of these curves shows the value along a horizontal cross section of the brightness diagram to the right. For b=1, the neutral curve with a slope of 45° gets applied. With decreasing b, the slope gets reduced — up to 0° at b=0. In this case the result is set to uniform black, removing all contrast from the image.

contrast angle

The slope α of such a curve is a measure for the local contrast change. For example, for a classic s-curve:

example: s-curve

Slopes less than 45° reduce the local contrast (blue), whereas slopes bigger than 45° increase it (red). The given s-curve increases the midtones’ local contrast at the expense of reduced contrast for shadows and highlights. During transitions, the neutral range of unchanged contrast (white) is crossed two times.

Contrast Change

With the given color code it is now possible to show the contrast change for all possible combinations of layer values. An offset of -45° is introduced, such that 0° now means neutral. For the ‘multiply’ mode this gives:

multiply: contrast diagram

The diagram to the right shows that the contrast change is independent of the base layer value a. With b=1 no contrast change happens. With decreasing b the local contrast gets gradually reduced until it gets removed completely at b=0.

It is important to note that this interpretation is only valid for uniform blend layers. A ‘contrast angle’ of \Delta|\alpha| = -45\,^{\circ} corresponding to a horizontal curve doesn’t necessarily mean that the result image is uniform. It just says that no ‘contrast information’ is taken from the base layer. This information could very well be taken from the other layer — as is the case with the ‘lighten’ mode, for example. Blending of local contrast gets looked at in more detail in the next section.

The slope gets calculated from the derivative with respect to a, so the contrast diagram shows an approximation of

\Delta|\alpha| = \left|\mathrm{arctan}\left(\frac{\partial}{\partial a} f(a,b)\right)\right| - \pi/4

example: ‘burn’ mode

Within the group of darkening blend modes, the ‘burn’ mode is special in that it is the only one which is capable of increasing the local contrast:

burn mode: brightness diff, curves and contrast diagram

The local contrast for midtones and highlights gets increased at the expense of clipping the shadows to pure black. The intensity of this effect depends on the value of b:
burn mode: influence the of blend layer value b

No changes happen for the neutral value b=1. At b=0.5, the darker half of the base layer tones is set to black while boosting the contrast for the remaining brighter tones. The most extreme effect is applied for b=0, where all values but a=1 are set to pure black.

Gradient Angle

This diagram type informs about inverting properties and blending of local contrast. The gradient of f(a,b) is a function which points in the direction of greatest brightness increase. With the help of a color code the gradient angle can be shown for all combinations of input values. A black color indicates where the gradient vanishes. Using the example of the ‘multiply’ mode:

multiply mode: gradient angle plot

The arrows overlayed on the brightness diagram to the left indicate the direction for a few samples of the gradient, whereas the plot on the right displays the gradient angle for all input combinations. The ‘multiply’ mode’s gradient angle features a smooth transition from 0° (red) over 45° (yellow) to 90° (green) when following the diagram clockwise.

inverting modes

gradient angle: legend inverting

For a blend mode to be non-inverting, increases of a or b must not lead to decreasing brightness. That is, the gradient must not point to the right or to the bottom. Or in other words, the gradient angle has to stay between 0 and 90 degrees.

The color code was chosen such that any amount of blue indicates an inverting blend mode. Obviously, ‘multiply’, as plotted above is a non-inverting blend mode.

local contrast blending

The gradient angle reveals from which layer the ‘contrast information’ is taken, that is small variations in brightness:

gradient angle: legend of local contrast blending

This can be illustrated by blending two special images: a horizontal gradient from black to white, overlayed with low-contrast horizontal stripes for the base layer, and the vertical version of that image (simply rotated by 90 degrees) for the blend layer. Using the ‘lighten’ mode this gives:

lighten mode: local contrast blending

Both the result image in the top left-hand corner as well as the gradient angle plotted on the right accurately reflect the definition of the lighten mode, which says to take either a or b as the result, whichever is brighter:

Last not least, the definition of the gradient angle is:

\phi = \mathrm{arctan}\left(\frac{\partial}{\partial b} f(a,b) / \frac{\partial}{\partial a}f(a,b)\right)

example: grain merge and grain extract

Putting it all together, here’s how the difference between ‘grain merge’ and ‘grain extract’ shows up in the various diagrams:

comparison of 'grain merge' and 'grain extract' blend modes

From right to left: the gradient angle diagrams reveal the most prominent difference between the two blend modes: ‘grain extract’ is an inverting mode. Where the gradient angle is defined, it is +45° (yellow) for ‘grain merge’, which indicates an equal share of local contrast from both layers, whereas for ‘grain extract’ the angle of -45° (magenta) means a mix of inverted blend layer and non-inverted base layer.

The brightness diagrams are vertically mirrored versions of each other, which indicates inversion of the blend layer. This shows up in the example image as a dominant orange color, which obviously stems from the inverted blend layer; the brightness characteristics of the base layer can be recognized in the result in non-inverted form.

The brightness difference plots, again, are vertically mirrored versions of each other. Finally, the formulas show that indeed ‘grain extract’ is the same as using ‘grain merge’ with an inverted blend layer.


  • 2009-10-08: new blend modes added; complementary modes completed


lake image (CC) courtesy of

gull image (CC) courtesy of marfis75,

Selected definitions:

  • darken: f(a,b) = \mathrm{min}(a,b)
  • multiply: f(a,b) = ab
  • burn: f(a,b) = \overline{\overline{a}/b} = 1-\frac{1-a}{b}
  • lighten: f(a,b) = \mathrm{max}(a,b)
  • screen: f(a,b) =  \overline{\overline{a} \overline{b}} = a+b-ab
  • dodge: f(a,b) = a/\overline{b} = \frac{a}{1-b}
  • normal: f(a,b) = b
  • hardlight:
  • overlay:
  • softlight (pegtop): f(a,b) = (1-2b)\cdot a^2 + 2b\cdot a
  • softlight (photoshop):

Brush Tester

September 9, 2009

How to visualize fuzzy brush outlines?

Here’s a Flash applet to test-drive the look and feel of various designs:

Other designs can be tested by simply replacing the PNGs (e.g. tester*.png) or editing brushes.xml from the download version (Flash 8 required).

Alternative downloads:
dhtml version (no Flash required, but no brush reload possible)
Flash10 version (faster, but buggy).

scratch & trash

August 30, 2009

Export multiple crops of the same Image

The Export dialog can support multiple exports from the same image. When each export branch has its own operations chain, everything is possible: invidiual scaling, sharpening, color space conversion and so on.

visible order of layer stack with blend modes

The black layer appears to be on top, even though it is below the red one in the layer stack.

legacy blend modes2

legacy blend modes

Noisy Ants

Quasimode Adjustments



Problems of HSV and HSL Color Models

Blending two orthogonal gray dithered gradients using blend mode “saturation”:

Decomposition of a dithered gray gradient:

Gradient Editor with Color Inspector

Motion Blur with decaying kernel

Polaroids; Hierarchical Tabs

Color management — postponed commit

Color management — dataflow, profiles

tabs degradation

tabs & icons & height

how to visualize feathered selections / fuzzy brush outlines?

Movies of xor-ed brush stamps:


Method used:
XOR background with 0x7FFF7F, blend result according to brush stamp alpha. circlehard050.avi and grunge050.avi have alpha reduced by 50%.

pop-menu for layer mode selection:


Adjusting table sort order

GIMP User Interface Modes

May 28, 2009

An illustrated description of GIMP’s basic image manipulation model from a user interface point of view: