Using XAML preferably,
I need to dynamically apply a gray-scale filter on a colored image from bottom to top. That's to say, i would like to be able to change the offset value of the gray-scale filter applied to my image pro grammatically.
For example, I would like to programmatically set 50% of the image in color (from the bottom of the image to its middle), and the other 50% of the image in gray-scale (e.g. from the middle of the image to its top).
I have read a lot of different answers, tried a lot of different things, and thought about a lot of different ways to do this.
- I could have two images, one on top of the other. One would be in gray-scale and the other would be in color. I would then programmatically change the size of the gray-scale image so that the image in color below it would partially show and create a sort of half-half view to the user.
However, this solution poses an issue that I do not seem to be able to resolve. When changing the height value of the gray-scale image, the image automatically rescale itself due to the 'Stretch' property which is set to Uniform (and that I do not wish to change to None).
Another way to do this would be to programmatically change the color pixels of the image. I have had some success with this in the past, however, this is too slow for what I am trying to do here (ideally, I would be changing the colors of the image from gray-scale to the original color of the image selected by the user every 50 milliseconds until a certain height is reached).
A third method could be to apply an Opacity Mask on the image and use
LinearGradientBrush
to change the offset value to the desired position. This is the code I am currently using, it works but simply apply a gray color to the image without changing the original colors of the image to gray-scale (resulting in a sort of a washed out colored image):
XAML:
<Image x:Name="myImage" HorizontalAlignment="Left" VerticalAlignment="Top" Source="C:\Users\Clement\Desktop\test.png" Canvas.Left="159" Canvas.Top="81" Width="500" Height="375" >
<Image.OpacityMask>
<LinearGradientBrush EndPoint="0.5,0" MappingMode="RelativeToBoundingBox" StartPoint="0.5,1">
<GradientStop x:Name="myImageLinearGradientBrushStop" Color="Black"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
Code-behind (in a timerEventProcessor that repeats itself every 50ms):
myImageLinearGradientBrushStop.Offset = percent * 0.01;
As mentioned previously, I have browsed a lot of different websites, read a lot of similar questions and tried a lot of different answers and still cant satisfactorily solve the problem.