3

I am trying to tint a System.Windows.Controls.Image. The image contains transparent areas and i'm just looking to tint the non transparent areas with a color.

For instance, the image is black/grey and tinting it red would result in a red gradient, with the transparent areas unaffected.

Is it possible to tint an Image in WPF either in XAML or the code behind (ideally) ?

Thank you

<Image Name="OverlayImage" Canvas.ZIndex="2" />

Example image:

enter image description here

PersuitOfPerfection
  • 1,009
  • 1
  • 15
  • 28
  • 1
    The simplest way would be to use a `Rectangle` fitted over the image filled with the color you want and with an opacity of around `0.5`. Otherwise, you're going to need to either use a [custom WPF Effect](https://msdn.microsoft.com/en-us/library/ee341370(v=expression.40).aspx) or [edit the pixel data directly](https://www.codeproject.com/Questions/106879/Set-Modify-pixels-in-a-BitmapImage). – Abion47 Mar 14 '17 at 18:35
  • Interesting. The problem is that these are full screen images, and are user contributed. Meaning that I don't know how tall/wide the non-transparent areas will be before hand. Pretty much ruling out the rectangle option :/ – PersuitOfPerfection Mar 14 '17 at 18:38
  • Not necessarily. When the image is supplied, you can do some math in the code behind to see where the image will be rendered. And there is actually a third option to use the image itself as the source for the `Rectangle`'s `OpacityMask`. See details [here](http://stackoverflow.com/questions/28247010/tint-a-partially-transparent-image-in-wpf). – Abion47 Mar 14 '17 at 18:40
  • In the example you linked, the person is setting the width and height to specific values. My image is literally full screen. 1920x1080 in this case. If I implement the code you linked to in your previous comment, and set the width/height to full screen, will the transparent areas also be tinted? – PersuitOfPerfection Mar 14 '17 at 18:43
  • No, because if the image is set to be the `OpacityMask` of the rectangle, the transparent areas will still be transparent. That's what an opacity mask does. – Abion47 Mar 14 '17 at 18:46
  • Aha, gotcha. Well i'll give that a shot then. I'l report back. Thanks – PersuitOfPerfection Mar 14 '17 at 18:47
  • @Abion47 Your advice to use this: http://stackoverflow.com/questions/28247010/tint-a-partially-transparent-image-in-wpf Worked great. Can you change your comment to an answer please so I can mark it is the solution? Cheers – PersuitOfPerfection Mar 14 '17 at 18:58

2 Answers2

17

As described in this answer, you can use a Rectangle to do the tinting. Setting the source of the rectangle's OpacityMask to be the same as the image itself will take care of making sure the transparent bits stay transparent.

<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>
Community
  • 1
  • 1
Abion47
  • 22,211
  • 4
  • 65
  • 88
0

A simple overlay won't do what you want.

I asked a similar question a while ago. The consensus was that you could achieve this using pixel shaders. The answers on my question provide a few options.

Community
  • 1
  • 1
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • 3
    All OP is doing is tinting all non-transparent pixels to a color. He isn't looking to preserve saturation or luminosity or anything like that, so a complex blending option with pixel shaders would be overkill. – Abion47 Mar 14 '17 at 19:21