使用 XAML 将彩色图像转换为灰度图像?
Transform a colored image to a grayscale image using XAML?
最好使用XAML,
我需要动态在彩色图像上从下到上应用灰度滤镜。也就是说,我希望能够以编程方式更改应用于我的图像的灰度滤镜的偏移值。
例如,我想以编程方式将图像的 50% 设置为彩色(从图像底部到中间),将图像的另外 50% 设置为灰度(例如从中间开始)图片的顶部)。
我已经阅读了很多不同的答案,尝试了很多不同的东西,并考虑了很多不同的方法来做到这一点。
- 我可以有两张图片,一张在另一张上面。一个是灰度的,另一个是彩色的。然后我会以编程方式更改灰度图像的大小,以便它下方的彩色图像会部分显示并为用户创建一种半对半视图。
但是,这个解决方案提出了一个我似乎无法解决的问题。当更改灰度图像的高度值时,由于 'Stretch' 属性 设置为统一(我不想更改为 None,因此图像会自动重新缩放).
另一种方法是以编程方式更改图像的颜色像素。过去我在这方面取得了一些成功,但是,这对于我在这里尝试做的事情来说太慢了(理想情况下,我会将图像的颜色从灰度更改为所选图像的原始颜色用户每 50 毫秒直到达到特定高度)。
第三种方法是在图像上应用不透明蒙版并使用LinearGradientBrush
将偏移值更改为所需位置。这是我目前正在使用的代码,它可以工作,但只需将灰色应用于图像而不会将图像的原始颜色更改为灰度(导致一种褪色的彩色图像):
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>
代码隐藏(在每 50 毫秒重复一次的 timerEventProcessor 中):
myImageLinearGradientBrushStop.Offset = percent * 0.01;
如前所述,我浏览了很多不同的网站,阅读了很多类似的问题,尝试了很多不同的答案,仍然无法令人满意地解决问题。
下面的XAML使用了一个两行的网格来显示两个图像在彼此之上。顶部图像的宽度和高度绑定到底部图像的大小,它跨越两个网格行。内部网格用于裁剪顶部图像。
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image x:Name="image" Grid.RowSpan="2" Source="..."/>
<Grid>
<Image Width="{Binding ActualWidth, ElementName=image}"
Height="{Binding ActualHeight, ElementName=image}"
HorizontalAlignment="Center" VerticalAlignment="Top">
<Image.Source>
<FormatConvertedBitmap Source="{Binding Source, ElementName=image}"
DestinationFormat="Gray8"/>
</Image.Source>
</Image>
</Grid>
</Grid>
感谢 Clemens 的帮助,我的问题得到了解决!
这是最终的 XAML 代码,供可能感兴趣的人使用:
<Grid Width="500" Height="375">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image x:Name="image" Grid.RowSpan="2" Source="C:\Users\Clement\Desktop\test_image.png" />
<Grid Margin="0,0,0,166" Grid.RowSpan="2">
<Image Width="{Binding ActualWidth, ElementName=image}"
Height="{Binding ActualHeight, ElementName=image}"
HorizontalAlignment="Center" VerticalAlignment="Top">
<Image.Source>
<FormatConvertedBitmap Source="{Binding Source, ElementName=image}"
DestinationFormat="Gray8"/>
</Image.Source>
<Image.OpacityMask>
<ImageBrush ImageSource="C:\Users\Clement\Desktop\test_image.png"/>
</Image.OpacityMask>
</Image>
</Grid>
</Grid>
这里我只是将 OpacityMask 添加到 Gray8 图像以恢复其透明度。
编码愉快!
最好使用XAML,
我需要动态在彩色图像上从下到上应用灰度滤镜。也就是说,我希望能够以编程方式更改应用于我的图像的灰度滤镜的偏移值。
例如,我想以编程方式将图像的 50% 设置为彩色(从图像底部到中间),将图像的另外 50% 设置为灰度(例如从中间开始)图片的顶部)。
我已经阅读了很多不同的答案,尝试了很多不同的东西,并考虑了很多不同的方法来做到这一点。
- 我可以有两张图片,一张在另一张上面。一个是灰度的,另一个是彩色的。然后我会以编程方式更改灰度图像的大小,以便它下方的彩色图像会部分显示并为用户创建一种半对半视图。
但是,这个解决方案提出了一个我似乎无法解决的问题。当更改灰度图像的高度值时,由于 'Stretch' 属性 设置为统一(我不想更改为 None,因此图像会自动重新缩放).
另一种方法是以编程方式更改图像的颜色像素。过去我在这方面取得了一些成功,但是,这对于我在这里尝试做的事情来说太慢了(理想情况下,我会将图像的颜色从灰度更改为所选图像的原始颜色用户每 50 毫秒直到达到特定高度)。
第三种方法是在图像上应用不透明蒙版并使用
LinearGradientBrush
将偏移值更改为所需位置。这是我目前正在使用的代码,它可以工作,但只需将灰色应用于图像而不会将图像的原始颜色更改为灰度(导致一种褪色的彩色图像):
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>
代码隐藏(在每 50 毫秒重复一次的 timerEventProcessor 中):
myImageLinearGradientBrushStop.Offset = percent * 0.01;
如前所述,我浏览了很多不同的网站,阅读了很多类似的问题,尝试了很多不同的答案,仍然无法令人满意地解决问题。
下面的XAML使用了一个两行的网格来显示两个图像在彼此之上。顶部图像的宽度和高度绑定到底部图像的大小,它跨越两个网格行。内部网格用于裁剪顶部图像。
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image x:Name="image" Grid.RowSpan="2" Source="..."/>
<Grid>
<Image Width="{Binding ActualWidth, ElementName=image}"
Height="{Binding ActualHeight, ElementName=image}"
HorizontalAlignment="Center" VerticalAlignment="Top">
<Image.Source>
<FormatConvertedBitmap Source="{Binding Source, ElementName=image}"
DestinationFormat="Gray8"/>
</Image.Source>
</Image>
</Grid>
</Grid>
感谢 Clemens 的帮助,我的问题得到了解决!
这是最终的 XAML 代码,供可能感兴趣的人使用:
<Grid Width="500" Height="375">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image x:Name="image" Grid.RowSpan="2" Source="C:\Users\Clement\Desktop\test_image.png" />
<Grid Margin="0,0,0,166" Grid.RowSpan="2">
<Image Width="{Binding ActualWidth, ElementName=image}"
Height="{Binding ActualHeight, ElementName=image}"
HorizontalAlignment="Center" VerticalAlignment="Top">
<Image.Source>
<FormatConvertedBitmap Source="{Binding Source, ElementName=image}"
DestinationFormat="Gray8"/>
</Image.Source>
<Image.OpacityMask>
<ImageBrush ImageSource="C:\Users\Clement\Desktop\test_image.png"/>
</Image.OpacityMask>
</Image>
</Grid>
</Grid>
这里我只是将 OpacityMask 添加到 Gray8 图像以恢复其透明度。
编码愉快!