Monthly Archives: April 2016

UWP Composition Effects: Temperature and Tint

In this article we discuss TemperatureAndTint, the Composition API effect that -unsurprisingly- allows you to adjust the temperature and/or tint of an image.

The Temperature property affects the balance between the blue and yellow colors in an image. Decreasing the color temperature makes an image look bluish. Increasing the temperature intensifies the green and red colors – in RGB-space this is the way to increase yellow. Here’s what happens to an image of a color wheel (image in the middle) when you decrease (image on the left) or increase (image on the right) the color temperature:

Temperature1 Temperature2 Temperature3

The Temperature property of the TemperatureAndTint effect does not stand for the color temperature of the image itself, for the relative change in color that is caused by the effect. It is defined as a float between –1 and 1.

The Tint property affects the balance between the green and magenta colors in an image. Increasing the tint increases the intensity of red and blue pixels, while decreasing increases the amount of green. Here’s the effect of changing the Tint in a color wheel image:

Tint1 Temperature2 Tint2

The Tint property is also a value in the range from -1 to 1.

What is Color Temperature?

The standard unit measure of Color Temperature is degrees Kelvin (K) -a variation of Centigrade a.k.a. degrees Celsius- and it ranges from 1000 to 10000. It was discovered in the late 1800’s at a Scottish barbecue. Physicist and mathematician Lord William Kelvin heated a block of carbon and observed its glow producing a range of different colors at different temperatures. The heated black cube first produced a dim red light, increasing to a brighter yellow as the temperature went up, and eventually produced a bright blue glow at the highest temperatures. These observations led to a color temperature scale based on a theoretical “ideal black body”.

Funny enough, the bluish light -which corresponds to the higher color temperature- is described as cool. So warm and cool refer to the color, not to the temperature.

Here’s how Kelvin’s color temperature scale looks like:


Most computer screens and televisions have a color temperature of 6500 K. That’s why you see a blue glow through the windows when you drive by someone’s house at night.

Let’s see how we can use the notion of Color Temperature on the Universal Windows Platform, and find some use cases for it.

How to apply the effect with the Composition API

In Visual Studio, make sure that your UWP project references the Microsoft UI Composition Toolkit project, and install the Win2D UWP Nuget package. For more info on the configuration and initialization of the different Composition API citizens, read my previous article.

When we create the effect, we give it a name. When we create an EffectFactory for the effect, we parameterize the Temperature and Tint properties:

// Create the effect, but don't specify the properties yet.
var temperatureAndTintEffect = new TemperatureAndTintEffect
    Name = "temperatureAndtint",
    Source = new CompositionEffectSourceParameter("source")

// Compile the effect
var effectFactory = _compositor.CreateEffectFactory(
    new[] { "temperatureAndtint.Temperature", "temperatureAndtint.Tint" });

Then we create a brush and apply it to the SpriteVisual:

// Create and apply the brush.
_brush = effectFactory.CreateBrush();
_spriteVisual.Brush = _brush;

There’s no base image loaded yet, so here’s how to load one in a CompositionSurfaceBrush  and plug that brush in the effect brush:

// Create CompositionSurfaceBrush
var surfaceBrush = _compositor.CreateSurfaceBrush();

// Create an image source to load
CompositionImage imageSource = _imageFactory.CreateImageFromUri(uri);
surfaceBrush.Surface = imageSource.Surface;

_brush.SetSourceParameter("source", surfaceBrush);

When you know the values that you want to apply to the Temperature and/or Tint properties of the effect (e.g. from a Slider control or data binding), then call InsertScalar:

private void ChangeTemperature(float temperature)
    // Apply parameter to brush.
    _brush.Properties.InsertScalar("temperatureAndtint.Temperature", temperature);

private void ChangeTint(float tint)
    // Apply parameter to brush.
    _brush.Properties.InsertScalar("temperatureAndtint.Tint", tint);

warning_thumb3  Tip: You can avoid hardcoded strings by using the nameof() operator.

Some of the Composition API effect related methods require parameters in the format, like “temperatureAndTint.Temperature”. With the nameof() operator you can get to the name of a variable, type, or member at runtime. That allows you to avoid the hard-coded strings to better survive refactorings.

Here’s how you could store the Temperature parameter and use it in the EffectFactory constructor:

// Strongly typed version of the "temperatureAndtint.Temperature" string
_temperatureParameter = temperatureAndTintEffect.Name 
	+ "." 
	+ nameof(temperatureAndTintEffect.Temperature);
var effectFactory = _compositor.CreateEffectFactory(
    new[] { _temperatureParameter, "temperatureAndtint.Tint" });

The value was stored in a field, so it can be reused when we apply the value:

_brush.Properties.InsertScalar(_temperatureParameter, temperature);

Using Color Temperature to adjust the lighting in photos

The most common use of Color Temperature in software is white-balancing pictures. Our brain automatically adapts to different lighting colors: we perceive a white T-shirt as white whether we are indoors and using warm artificial lighting or outdoors in sunlight. Our eyes and brain recalibrate what we read as white, based on our experience and points of reference, but a camera does not. When taking a picture, the camera needs to be properly configured to the correct color temperature setting. If it’s not well done, the image needs to post-processed.

Many photo editor apps come with a slider for the Temperature in the Red-White-Blue scale, and a slider for the Tint in the Green to Magenta scale to do minor adjustments.

That’s exactly what the sample app does, so let’s move to other usages of Color Temperature.

Using Color Temperature to adapt a display to the time of day

The TemperatureAndTint effects provides you with an opportunity to make text better readable and interacting with your app more comfortable and less fatiguing. If you are reading a book, the pages will always appear white – no matter what light source you’re under. But pure white is not always the ideal background. For some apps, it makes sense to adjust the background color based on your user’s environment (indoors or outdoors) or the time of day (day or night): blue is a better background in full sunlight, and soft yellow-to-orange tones are better for reading bed-time stories. There already is a huge range of apps available that monitor the light conditions (or use history data) and adapt the screen setting accordingly. For a good example, take a look at f.lux.

Apps on the Universal Windows Platforms have no write access to screen settings and system colors. But nothing prevents you from using a pale background image in your app and changing its color temperature through the Composition API.

Here’s what happens when you load a white gradient bitmap into the sample app and change the color temperature:

White1 White2 White3

Using Color Temperature to highlight an area

The Color Temperature effect is not only useful on a white background. The following screenshots show the effect in action against a colorful (blue and red) background:

Colorful1 Colorful2 Colorful3

In the image on the left, the blue area is nicely highlighted. In the image on the right, the red area gets all the attention. So adjusting the Color Temperature (or Tint) can be used to temporarily highlight different zones in your UWP app, and this can be done with animation.

The Code

The sample app lives here on GitHub. The Assets folder in the main project has other sample images for you to experiment with: people, flowers, buildings…



UWP Composition Effects: Hue Rotation

In this article we play around with the Hue Rotation effect, which is one of the UWP Composition Effects. This effect allows you to apply a rotation to all of the colors of an image in real-time. The effect takes one parameter -the rotation angle- which is a float value between 0 and 2π.

The best way to demonstrate the Hue Rotation, is to apply it on an image of a color wheel. By changing the angle of the effect, the image seems to rotate physically. Here are some screenshots of the sample app that I wrote. It applies the Hue Rotation effect on some images. The rotation angle of the effect is controlled by a slider:




When you move the slider slowly from its minimum to its maximum value, you’ll see that the image appears to rotate clockwise. It looks like a RotateTransform, but we’re actually just shifting the colors of the bitmap. The color shift is not linear however: for some rotation angles the yellow range entirely disappears – like in the screenshot in the middle. That’s because in color theory nothing is linear: everything is based on non-linear physical characteristics as well as on biological ones (how the human eye works). There is an awesome and well-readable introduction to all of this right here.

So rotating colors may look easy at first sight, but it’s definitely not. The Hue Rotation effect actually applies a color matrix in the red-green-blue space. The matrix depends on the rotation angle.

Enough introduction, let’s fire up Visual Studio now.

Preparing the project

The core components of the Composition API are built into the UWP platform. On top of that, the sample app makes use of the Microsoft UI Composition Toolkit. That’s a small helper library, written in C++, that facilitates loading bitmap images into composition visuals:


When you want to use one or more of the Composition API effects in your UWP app, then you also need to add the Win2D UWP Nuget package:


One line of XAML

The Composition API sits between XAML and DirecX, so XAML-wise there is not much to do: it suffices to define a host element for the image. A named Grid control will do:

<Grid x:Name="Container" Margin="0" />

Creating and applying the effect

For the C# part, we start with defining some fields in the View’s code-behind. We define

private Compositor _compositor;
private ContainerVisual _root;
private CompositionImageFactory _imageFactory;
private SpriteVisual _spriteVisual;
private CompositionEffectBrush _brush;

When the page is loaded, we initialize the infrastructure:

// Initialize Composition UI infrastructure.
_root = Container.GetVisual();
_compositor = _root.Compositor;
_imageFactory = 

We make use of the following extension method to create the placeholder:

public static class UIElementExtensions
    public static ContainerVisual GetVisual(this UIElement element)
        var hostVisual = ElementCompositionPreview.GetElementVisual(element);
        var root = hostVisual.Compositor.CreateContainerVisual();
        ElementCompositionPreview.SetElementChildVisual(element, root);
        return root;

Here’s how to create the sprite visual, and hook it into the XAML visual tree:

// Hook the sprite visual into the XAML visual tree.
_spriteVisual = _compositor.CreateSpriteVisual();
var side = (float)Math.Min(
	Presenter.ActualWidth, Presenter.ActualHeight);
_spriteVisual.Size = new Vector2(side, side);

All the previous code is further explained in this article of mine on the basics of the Composition API.

Let’s now dive into the effect related code. The next couple of steps create the Hue Rotation effect:

  • We first define the effect, where we specify the name of the image brush that will be used as Source, but we omit the Angle.
  • Then we compile it with CreateEffectFactory() where we specify the parameterized properties (i.c. the Angle) in an EffectName.PropertyName syntax, and
  • create a brush that holds the effect, through CreateBrush().
  • Finally we apply that brush to the sprite visual:
// Create the effect, but don't specify the Angle yet.
var hueRotationEffect = new HueRotationEffect
    Name = "hueRotation",
    Source = new CompositionEffectSourceParameter("source")

// Compile the effect
var effectFactory = _compositor.CreateEffectFactory(
	new[] { "hueRotation.Angle" });

// Create and apply the brush.
_brush = effectFactory.CreateBrush();
_spriteVisual.Brush = _brush;

An effect needs pixels to work on, so it is always chained to a CompositionSurfaceBrush which can hold a color, a bitmap, or an effect.

Here’s how to load a bitmap into a brush:

private void LoadImage(Uri uri)
    // Create CompositionSurfaceBrush
    var surfaceBrush = _compositor.CreateSurfaceBrush();

    // Create an image source to load
    CompositionImage imageSource = _imageFactory.CreateImageFromUri(uri);
    surfaceBrush.Surface = imageSource.Surface;

    _brush.SetSourceParameter("source", surfaceBrush);

The last line of the previous snippet  –the SetSourceParameter() call- connects the effect brush to the image brush.

When we created the effect, we parameterized the hue rotation angle. This allows animation and programmatic access. When the rotation angle changes, there’s no need to reload or redraw the bitmap. We only need to apply a new value to the angle. :

private void RotateHue(float angle)
    // Apply parameter to brush.
    _brush.Properties.InsertScalar("hueRotation.Angle", angle);

We now have a nice playground to test the effect on different images.

What about black and white?

The Hue Rotation effect should not recolor black, grey, or white pixels, since these are not on the color wheel. And indeed, when we load a black and white gradient image into the sprite visual and apply the effect, nothing changes:


A real life example

Here’s an example of where the Hue Rotation effect could be used in an app. Let’s take a look at the Color Picker from WinRT XAML Toolkit in action:


For a human it’s hard to find or define a color by just using sliders for the amount of red, green, and blue (RGB). Most color pickers use another standard to describe the same set of colors: HSL or HSV, where

  • H stands for Hue. This is the color’s position on the color wheel, generally expressed in degrees from 0° to 359° where 0° represents red and 180° corresponds to red’s opposite color – cyan.
  • S stands for Saturation, the purity of the color, or how far it is from any shade of grey. It is expressed as a percentage.
  • L and V stand for Lightness and Value (a.k.a Brightness). These are two different ways of specifying how far away the color is from black. Both are expressed as a percentage.

For more definitions (chroma, luma, luminance, colorfulness and so on) and more exact definitions and formulas, start reading here.

The color wheel on the outside of the color picker, allows you to easily pick the base color (the Hue). The triangle on the inside manages the two other properties: Brightness and Saturation.

If you dive into the code of the WinRT XAML Toolkit Color Picker Sample, you’ll notice that after every Hue change, the inner triangle is entirely redrawn pixel by pixel. The control  calls the RenderColorPickerSaturationLightnessTriangleCore() method in WriteableBitmapColorPickerExtensions. When the size of the control changes, the same algorithm is applied and everything is redrawn pixel by pixel.

All in all, that’s a pretty heavy operation, and I can imagine that some hardware –like a cheap phone or an IoT device- will choke on this.

This is a scenario where the Composition API and the Hue Rotation effect in particular can come to the rescue. The following set of screenshots show the impact of Hue Rotation on a monochromatic image. The main color of the image is changed but the white, black, and grey tones are unaffected, and that’s exactly what the color picker needs:




The image is never redrawn, only its colors are shifted. I can confirm that it runs smoothly on the phone:


The code

The sample app is here on GitHub. It will be extended with demos of other Composition API effects.