WPF中如何为图片着色?选中变色时图形不一致问题求助
解决方案
一、修正原OpacityMask实现(解决形状不一致问题)
你遇到的形状偏差,大概率是因为Image和Rectangle的缩放/对齐规则不一致,以及ImageBrush未设置拉伸模式导致的。调整代码如下:
<Grid Margin="5,0,0,0" Width="25" Height="25"> <!-- 原始图标 --> <Image Source="{Binding ItemImageSource}" Stretch="UniformToFill" RenderOptions.BitmapScalingMode="Fant"/> <!-- 选中状态的颜色遮罩 --> <Rectangle Fill="{StaticResource orangePink}" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}"> <Rectangle.OpacityMask> <ImageBrush ImageSource="{Binding ItemImageSource}" Stretch="UniformToFill"/> </Rectangle.OpacityMask> </Rectangle> </Grid>
关键点:
- 给Grid固定宽高,确保子元素布局范围一致
Image和ImageBrush都设置Stretch="UniformToFill",保证缩放规则统一- 给遮罩Rectangle绑定选中状态的Visibility,避免未选中时也叠加遮罩
- 确保
RenderOptions.BitmapScalingMode拼写一致(原代码中的Fant是正确值)
二、使用SVG矢量图标(推荐,适配高分辨率且变色更稳定)
高分辨率位图缩放仍可能出现边缘偏差,改用SVG矢量图标可以彻底解决变形问题,推荐使用SharpVectors库:
- 安装NuGet包:
SharpVectors.Wpf - 用
SvgImage控件展示图标,通过ColorTransform实现选中变色:
<svgc:SvgImage x:Name="Icon" Source="{Binding IconSvgPath}" Width="25" Height="25" RenderOptions.BitmapScalingMode="Fant"> <svgc:SvgImage.Style> <Style TargetType="svgc:SvgImage"> <Setter Property="ColorTransform" Value="#FF000000"/> <!-- 默认黑色 --> <Style.Triggers> <DataTrigger Binding="{Binding IsSelected}" Value="True"> <Setter Property="ColorTransform" Value="{StaticResource orangePink}"/> <!-- 选中颜色 --> </DataTrigger> </Style.Triggers> </Style> </svgc:SvgImage.Style> </svgc:SvgImage>
注意: 需要在XAML头部添加命名空间:xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
三、使用MaterialDesignThemes库(快速实现专业图标效果)
如果不想自己实现,MaterialDesignThemes提供了开箱即用的图标控件,支持选中状态变色:
- 安装NuGet包:
MaterialDesignThemes - 使用
PackIcon控件:
<materialDesign:PackIcon Kind="{Binding IconKind}" Width="25" Height="25"> <materialDesign:PackIcon.Style> <Style TargetType="materialDesign:PackIcon"> <Setter Property="Foreground" Value="Gray"/> <!-- 默认颜色 --> <Style.Triggers> <DataTrigger Binding="{Binding IsSelected}" Value="True"> <Setter Property="Foreground" Value="{StaticResource orangePink}"/> <!-- 选中颜色 --> </DataTrigger> </Style.Triggers> </Style> </materialDesign:PackIcon.Style> </materialDesign:PackIcon>
命名空间: xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
四、将位图转为DrawingImage实现变色
如果必须使用位图,可将其转为DrawingImage,通过DrawingGroup的ColorTransform修改颜色:
// 后台代码:将BitmapImage转为带颜色变换的DrawingImage public DrawingImage GetColoredImage(BitmapImage source, Color targetColor) { var imageDrawing = new ImageDrawing(source, new Rect(0, 0, source.PixelWidth, source.PixelHeight)); var drawingGroup = new DrawingGroup(); drawingGroup.Children.Add(imageDrawing); // 应用颜色变换 var colorMatrix = new ColorMatrix { Matrix3x3 = new Matrix3x3( targetColor.ScR, targetColor.ScG, targetColor.ScB, targetColor.ScR, targetColor.ScG, targetColor.ScB, targetColor.ScR, targetColor.ScG, targetColor.ScB) }; drawingGroup.Transform = new ColorMatrixTransform(colorMatrix); return new DrawingImage(drawingGroup); }
然后在XAML中绑定DrawingImage,通过触发器切换选中状态的资源。
内容的提问来源于stack exchange,提问作者Ahmed Al-Ghanim
相关产品推荐
相关产品推荐

