5

How can I tint/colorize an image in WPF (using MVVM) without sacrificing performance? A purely XAML solution would be ideal, as modifying bitmaps in the code will cause performance loss with lots of changing images. The image is made up of more than simple shapes, so it is not possible using a path.

Cyral
  • 12,859
  • 5
  • 40
  • 78

1 Answers1

8

Unlike WinForms/GDI+, WPF does not seem to contain any easy ways to colorize/tint an image as it is being rendered. Two ideas for accomplishing this are, using a shader, or overlaying a colored rectangle over the image.

I decided to try the rectangle route and found that it works. Basically, all you need to do is overlay a colored rectangle over your image, and use an OpacityMask to restrict the color fill to a certain area. OpacityMask is primarily used with paths, but it can take any kind of brush, including an ImageBrush. This means you can use your image as a "stencil" for the colored fill.

Example: (Taken from my application where a user can "highlight" a section of a map, the actual image looks like this)

Before Overlay & Mask

http://i.imgur.com/rdI7LGq.png

After Overlay & Mask

http://i.imgur.com/WkJdmvG.png

Here is all of the required XAML for this:

<Image
    Source="{Binding MyImage}"
    Width="150"
    Height="150" />
<Rectangle Width="150" Height="150">
    <Rectangle.Fill>
        <SolidColorBrush Color="{Binding Color}"/>
    </Rectangle.Fill>
    <Rectangle.OpacityMask>
        <ImageBrush ImageSource="{Binding MyImage}"/>
    </Rectangle.OpacityMask>
</Rectangle>

To bind the color to a brush as I did, use a ColorToBrushConverter.

Community
  • 1
  • 1
Cyral
  • 12,859
  • 5
  • 40
  • 78
  • You could save the ColorToBrushConverter by creating a SolidColorBrush instance in XAML and binding its Color property like ``. – Clemens Jan 31 '15 at 08:39