Hi, my name is Simon Tao and I’m a program manager on the Win2D team. I’d like to talk about a feature we recently added to Win2D, image effects, and the awesome things you can do with them. As always, we’d love to hear your feedback as to how easy/hard it is to accomplish your tasks in Win2D, and what direction you want us to take including what should be prioritized in our backlog.
This is part 1 of a 3 part series; I’ll update the links to each part as they are published.
Image effects, also known as filter effects, are a powerful tool for applying visual effects and performing processing on bitmaps and other graphical data. Some common examples of image effects include:
- Gaussian blur
- Hue rotation
You can see what these four examples look like below:
Saturation effect (saturation = 0.25)
Gaussian blur effect (blur amount = 10)
Hue rotation effect (angle = 130)
Blend effect (blend mode = linear dodge)
Source image is a banana and destination image is an apple
Of course, these examples only scratch the surface of what image effects are capable of. In this series of posts I will go over some key concepts and walk you through an end-to-end example to show the kinds of cool (and hot!) visual effects you can accomplish with Win2D.
What is an image effect?
Win2D image effects are comprised of a few core parts:
Fundamentally, an image effect is a graphical operation that is applied to pixel data, where operation refers to anything that can be expressed using a DirectX HLSL shader. I’ll talk more about the implementation details of effects in a later part of this series.
Effects can take zero or more input images. From the above examples, Gaussian blur, saturation, and hue rotation are one-input effects, while blend is a two-input effect.
An effect can expose properties that allow you to control its behavior. Properties can be numerics (e.g. rotation angle = 130), enumerations (e.g. blend mode = linear dodge), or more complex types.
Finally, all effects produce a single output image.
Example 1: Gaussian blur
Let’s look at the previous diagram as applied to the Gaussian blur effect:
This effect takes the input image and applies a Gaussian blur with blur radius of 10 device-independent units.
To implement this, add the following code to your Canvas_Draw method:
var blur = new GaussianBlurEffect();
blur.BlurAmount = 10.0f;
blur.Source = myBitmap;
myBitmap is a CanvasBitmap that contains the image to be blurred.
What content can I apply image effects to?
In short, any content in Win2D! This includes geometry, text, bitmaps and other effects.
The longer answer is that a valid effect input is any graphics content that is capable of providing pixel data. This capability is encapsulated in the IEffectInput interface. Bitmaps and other effects can natively produce pixels and implement IEffectInput. However, geometry and text in Win2D are currently treated as vector content, and you first need to draw them into a CanvasRenderTarget in order to realize them into a pixel-based form.
In the future we plan to add support for command lists which will allow geometry and text to be used directly as effect inputs, skipping the render target intermediate.
Example 2: Gaussian blur on text
Let’s apply a Gaussian blur to some text. This requires an additional step vs. blurring a bitmap.
Your Canvas_Draw method should look like this:
var myBitmap = new CanvasRenderTarget(sender, 300, 50);
using (var ds = myBitmap.CreateDrawingSession())
ds.Clear(Color.FromArgb(0, 0, 0, 0));
ds.DrawText(“Effects are cool”, 0, 0, Colors.White);
var blur = new GaussianBlurEffect
BlurAmount = 3.0f, // Use a smaller blur amount for text.
Source = myBitmap
The first five lines create the CanvasRenderTarget and draw the text into it. Everything after var blur = new GaussianBlurEffect is essentially identical to the first example, but we are now using initializer syntax: you can directly initialize an effect’s properties when you construct it, which can be more readable.