【问题标题】:Convertor on ImageSource - convert image to grayscaleImageSource 上的转换器 - 将图像转换为灰度
【发布时间】:2026-02-08 20:10:01
【问题描述】:

我在图像控件上有多重绑定。我绑定了两个属性,一个是 bool 类型(IsLogged),一个是 typeof Uri(ProfilePhoto)。

XAML:

                                <Image.Source >
                                    <MultiBinding Converter="{StaticResource avatarConverter}">
                                        <Binding Path="ProfilePhoto"></Binding>
                                        <Binding Path="StatusInfo.IsLogged"></Binding>
                                    </MultiBinding>
                                </Image.Source>
                            </Image>

我创建转换器,如果属性 IsLogged 为 false,它将 BitmapImage 转换为灰度。

看起来像这样:

public class AvatarConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var image = values[0] as BitmapImage;

        string s = values[1].ToString();

        bool isLogged = System.Convert.ToBoolean(s);

        if (!isLogged)
        {
            try
            {
                if (image != null)
                {
                    var grayBitmapSource = new FormatConvertedBitmap();
                    grayBitmapSource.BeginInit();
                    grayBitmapSource.Source = image;
                    grayBitmapSource.DestinationFormat = PixelFormats.Gray32Float;
                    grayBitmapSource.EndInit();
                    return grayBitmapSource;
                }
                return null;

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        return image;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

如果我只绑定BitmapImage的图像源属性类型,效果很好,但我需要绑定Uri的属性类型。

我害怕在转换器中创建变量 BitmapImage 并作为源使用 Uri。 将此变量作为图像源返回。我认为这不是理想的方式。也许我错了。

你的意见是什么

一些优雅的解决方案?

【问题讨论】:

    标签: wpf image uri converter


    【解决方案1】:

    虽然您可以使用转换器来实现,但还有一个更好的选择:使用着色器效果。您将在 this page 上找到 GreyscaleEffect 的实现。

    <Style x:Key="grayedIfNotLogged" TargetType="Image">
        <Style.Triggers>
            <DataTrigger Binding="{Binding StatusInfo.IsLogged}" Value="False">
                <Setter Property="Effect">
                    <Setter.Value>
                        <fx:GrayscaleEffect />
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
    
    ...
    
    <Image Source="..." Style="{StaticResource grayedIfNotLogged}" />
    

    【讨论】:

    • 感谢有趣的解决方案,我试试看。
    • 你的 'fx' 映射到哪个 xml 命名空间
    • @LordWilmore,不知道...我参加 GreyscaleEffect 课程的页面不再可用。
    • 完美。谢谢。