【问题标题】:Imagescaling looking bad in Ribbon图像缩放在功能区中看起来很糟糕
【发布时间】:2012-06-04 16:55:51
【问题描述】:

我正在基于 MS RibbonControlsLibrary (3.5.41019.1) 以编程方式填充功能区 (WPF)。所有图像(最引人注目的大图像)看起来都非常糟糕且“像素化”:

  • 顶部屏幕截图来自“pixly”功能区(图像缩放看起来很糟糕)
  • 底部屏幕截图取自基于 WinForms 的窗口中的同一区域,具有相同的源图像(图像缩放看起来不错)
  • 所有图片都保存在 32 位 PNG 48x48

我尝试将BitmapScalingMode设置为“HighQuality”没有任何效果,源代码:

BitmapImage img = new BitmapImage();
try
{
    Uri uri = new Uri("pack://application:,,,/UIMainWindow;component/Resources/" + iPictureName);                
    img.BeginInit();
    img.SetValue(BitmapImage.CacheOptionProperty, BitmapCacheOption.OnLoad);
    RenderOptions.SetBitmapScalingMode(img, BitmapScalingMode.HighQuality);
    img.UriSource = uri;
    img.EndInit();
    img.Freeze();
}
catch (Exception ex)
{
    throw new Exception("Creation of image failed: " + ex.Message, ex);
}

问题 为什么图像的缩放看起来很糟糕?我该如何解决这个问题?

【问题讨论】:

    标签: wpf image render ribbon antialiasing


    【解决方案1】:

    以上其他答案均不适合我,因此我开始了自己的调查。将图像大小调整为 32x32几乎 解决了这个问题,但我们有不同 DPI 设置的用户,图像在他们的机器上无法正确缩放。我还应该注意,我正在使用 System.Windows.Controls.Ribbon 程序集,它的行为可能与 RibbonControlsLibrary 略有不同。

    我发现 RibbonButton 的默认 ControlTemplate 已明确指定 NearestNeighbor 作为位图缩放选项。好消息是,通过将样式放入 Window 的资源中,很容易覆盖此控件模板。有点坏的消息是控件模板非常冗长。我将系统上 RibbonButton 的默认 ControlTemplate 转储到一个文件中,并更改了位图缩放选项。

    首先,如果您还没有此命名空间声明,则需要在文件顶部声明:

    xmlns:s="clr-namespace:System;assembly=mscorlib"
    

    然后将此样式放入窗口的资源中以覆盖 RibbonButton 外观:

    <Style TargetType="RibbonButton">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="RibbonButton">
                    <Border BorderThickness="{TemplateBinding Border.BorderThickness}" CornerRadius="{TemplateBinding RibbonControlService.CornerRadius}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="OuterBorder" SnapsToDevicePixels="True">
                        <Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}" CornerRadius="{TemplateBinding RibbonControlService.CornerRadius}" BorderBrush="#00FFFFFF" Name="InnerBorder">
                            <StackPanel Name="StackPanel">
                                <Image Source="{TemplateBinding RibbonControlService.LargeImageSource}" Name="PART_Image" Width="32" Height="32" Margin="{DynamicResource {ComponentResourceKey TypeInTargetAssembly=Ribbon, ResourceId=LargeImageMargin}}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="Center" RenderOptions.BitmapScalingMode="HighQuality" />
                                <Grid Name="Grid" HorizontalAlignment="Center" VerticalAlignment="Center">
                                    <RibbonTwoLineText TextAlignment="Center" LineHeight="13" LineStackingStrategy="BlockLineHeight" Text="{TemplateBinding RibbonControlService.Label}" Name="TwoLineText" Margin="1,1,1,0" HorizontalAlignment="Center" VerticalAlignment="Top" />
                                </Grid>
                            </StackPanel>
                        </Border>
                    </Border>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding Path=ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Mode=Self}}" Value="Large">
                            <Setter Property="FrameworkElement.MinWidth">
                                <Setter.Value>
                                    <s:Double>44</s:Double>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="FrameworkElement.Height">
                                <Setter.Value>
                                    <s:Double>66</s:Double>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="FrameworkElement.MinHeight" TargetName="Grid">
                                <Setter.Value>
                                    <s:Double>26</s:Double>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="RibbonTwoLineText.HasTwoLines" TargetName="TwoLineText">
                                <Setter.Value>
                                    <s:Boolean>True</s:Boolean>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Mode=Self}}" Value="Small">
                            <Setter Property="FrameworkElement.Height">
                                <Setter.Value>
                                    <s:Double>22</s:Double>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="FrameworkElement.Margin" TargetName="PART_Image">
                                <Setter.Value>
                                    <Thickness>1,0,1,0</Thickness>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Image.Source" TargetName="PART_Image">
                                <Setter.Value>
                                    <Binding Path="SmallImageSource" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="FrameworkElement.Width" TargetName="PART_Image">
                                <Setter.Value>
                                    <s:Double>16</s:Double>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="FrameworkElement.Height" TargetName="PART_Image">
                                <Setter.Value>
                                    <s:Double>16</s:Double>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="FrameworkElement.HorizontalAlignment" TargetName="TwoLineText">
                                <Setter.Value>
                                    <x:Static Member="HorizontalAlignment.Left" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="FrameworkElement.Margin" TargetName="TwoLineText">
                                <Setter.Value>
                                    <Thickness>1,1,1,1</Thickness>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="StackPanel.Orientation" TargetName="StackPanel">
                                <Setter.Value>
                                    <x:Static Member="Orientation.Horizontal" />
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Mode=Self}}" Value="Small" />
                                <Condition Binding="{Binding Path=IsInQuickAccessToolBar, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="FrameworkElement.Height">
                                <Setter.Value>
                                    <s:Double>NaN</s:Double>
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                        <DataTrigger Binding="{Binding Path=ControlSizeDefinition.IsLabelVisible, RelativeSource={RelativeSource Mode=Self}}" Value="False">
                            <Setter Property="UIElement.Visibility" TargetName="TwoLineText">
                                <Setter.Value>
                                    <x:Static Member="Visibility.Collapsed" />
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=ControlSizeDefinition.ImageSize, RelativeSource={RelativeSource Mode=Self}}" Value="Collapsed">
                            <Setter Property="UIElement.Visibility" TargetName="PART_Image">
                                <Setter.Value>
                                    <x:Static Member="Visibility.Collapsed" />
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <Trigger Property="UIElement.IsMouseOver">
                            <Setter Property="Panel.Background" TargetName="OuterBorder">
                                <Setter.Value>
                                    <Binding Path="MouseOverBackground" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <Binding Path="MouseOverBorderBrush" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                                <Setter.Value>
                                    <SolidColorBrush>#80FFFFFF</SolidColorBrush>
                                </Setter.Value>
                            </Setter>
                            <Trigger.Value>
                                <s:Boolean>True</s:Boolean>
                            </Trigger.Value>
                        </Trigger>
                        <Trigger Property="UIElement.IsKeyboardFocused">
                            <Setter Property="Panel.Background" TargetName="OuterBorder">
                                <Setter.Value>
                                    <Binding Path="FocusedBackground" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <Binding Path="FocusedBorderBrush" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                                <Setter.Value>
                                    <SolidColorBrush>#80FFFFFF</SolidColorBrush>
                                </Setter.Value>
                            </Setter>
                            <Trigger.Value>
                                <s:Boolean>True</s:Boolean>
                            </Trigger.Value>
                        </Trigger>
                        <Trigger Property="ButtonBase.IsPressed">
                            <Setter Property="Panel.Background" TargetName="OuterBorder">
                                <Setter.Value>
                                    <Binding Path="PressedBackground" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <Binding Path="PressedBorderBrush" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                                <Setter.Value>
                                    <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                                </Setter.Value>
                            </Setter>
                            <Trigger.Value>
                                <s:Boolean>True</s:Boolean>
                            </Trigger.Value>
                        </Trigger>
                        <Trigger Property="RibbonControlService.IsInControlGroup">
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <Binding Path="Ribbon.BorderBrush" RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderThickness" TargetName="OuterBorder">
                                <Setter.Value>
                                    <Thickness>0,0,1,0</Thickness>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                                <Setter.Value>
                                    <CornerRadius>0,0,0,0</CornerRadius>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.CornerRadius" TargetName="InnerBorder">
                                <Setter.Value>
                                    <CornerRadius>0,0,0,0</CornerRadius>
                                </Setter.Value>
                            </Setter>
                            <Trigger.Value>
                                <s:Boolean>True</s:Boolean>
                            </Trigger.Value>
                        </Trigger>
                        <Trigger Property="UIElement.IsEnabled">
                            <Setter Property="UIElement.Opacity" TargetName="PART_Image">
                                <Setter.Value>
                                    <s:Double>0.5</s:Double>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                                <Setter.Value>
                                    <SolidColorBrush>#FF9E9E9E</SolidColorBrush>
                                </Setter.Value>
                            </Setter>
                            <Trigger.Value>
                                <s:Boolean>False</s:Boolean>
                            </Trigger.Value>
                        </Trigger>
                        <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True">
                            <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.MenuTextBrushKey}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Panel.Background" TargetName="OuterBorder">
                                <Setter.Value>
                                    <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                                <Setter.Value>
                                    <CornerRadius>0,0,0,0</CornerRadius>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True" />
                                <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightBrushKey}" />
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True" />
                                <Condition Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="False" />
                                <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource Mode=TemplatedParent}, FallbackValue=false}" Value="True" />
                                <Condition Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="False" />
                                <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightBrushKey}" />
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                                <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Panel.Background" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightBrushKey}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                                <Setter.Value>
                                    <CornerRadius>0,0,0,0</CornerRadius>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                                <Setter.Value>
                                    <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=IsKeyboardFocused, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                                <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Panel.Background" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightBrushKey}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                                <Setter.Value>
                                    <CornerRadius>0,0,0,0</CornerRadius>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="InnerBorder">
                                <Setter.Value>
                                    <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                                <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Panel.Background" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.ControlDarkBrushKey}" />
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Border.CornerRadius" TargetName="OuterBorder">
                                <Setter.Value>
                                    <CornerRadius>0,0,0,0</CornerRadius>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=IsInControlGroup, RelativeSource={RelativeSource Mode=Self}}" Value="True" />
                                <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Border.BorderBrush" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.ControlLightLightBrushKey}" />
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="False" />
                                <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="True" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="TextElement.Foreground" TargetName="OuterBorder">
                                <Setter.Value>
                                    <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                                </Setter.Value>
                            </Setter>
                        </MultiDataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,我创建了自己的用户控件来解决这个问题。

      我就是这样做的:

      <ribbon:Ribbon>
              <ribbon:RibbonTab Header="File">
                  <ribbon:RibbonGroup Header="File">
                      <views:ImageButton Command="{Binding LoadCommand}" Caption="Open" SourceImage="/Images/save.png"/>
                  </ribbon:RibbonGroup>
              </ribbon:RibbonTab>
          </ribbon:Ribbon>
      

      图像按钮用户控件ImageButton.xaml

      <UserControl Name="control"
      
       <Button Command="{Binding Command, ElementName=control}" Style="{x:Null}">
          <StackPanel>
              <infrastructure:AutoGreyableImage Width="32" Source="{Binding SourceImage, ElementName=control}"/>
              <TextBlock Text="{Binding Caption, ElementName=control}"/>
          </StackPanel>
      </Button>
      

      图像按钮用户控件ImageButton.xaml.cs

      public partial class ImageButton : UserControl
      {
          public static DependencyProperty CommandProperty = DependencyProperty.Register(
            "Command", typeof(ICommand), typeof(ImageButton));
          public static DependencyProperty SourceProperty = DependencyProperty.Register(
            "SourceImage", typeof(string), typeof(ImageButton));
          public static DependencyProperty CaptionProperty = DependencyProperty.Register(
            "Caption", typeof(string), typeof(ImageButton));
      
          public ICommand Command
          {
              get
              {
                  return (ICommand)GetValue(CommandProperty);
              }
              set
              {
                  SetValue(CommandProperty, value);
              }
      
          }
          public string SourceImage
          {
              get
              {
                  return (string)GetValue(SourceProperty);
              }
              set
              {
                  SetValue(SourceProperty, value);
              }
      
          }
          public string Caption
          {
              get
              {
                  return (string)GetValue(CaptionProperty);
              }
              set
              {
                  SetValue(CaptionProperty, value);
              }
      
          }
          public ImageButton()
          {
              InitializeComponent();
          }
      }
      

      对于 AutogreyableImage,我使用了this post

      这是类的复制粘贴

          using System.Windows.Controls;
          using System.Windows.Media;
          using System.Windows.Media.Imaging;  
      
      
      /// <summary>
          /// Class used to have an image that is able to be gray when the control is not enabled.
          /// Author: Thomas LEBRUN (http://blogs.developpeur.org/tom)
          /// </summary>
          public class AutoGreyableImage : Image
          {
      
              /// <summary>
              /// Initializes a new instance of the <see cref="AutoGreyableImage"/> class.
              /// </summary>
              static AutoGreyableImage()
              {
                  // Override the metadata of the IsEnabled property.
                  IsEnabledProperty.OverrideMetadata(typeof(AutoGreyableImage), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnAutoGreyScaleImageIsEnabledPropertyChanged)));
              }
      
              /// <summary>
              /// Called when [auto grey scale image is enabled property changed].
              /// </summary>
              /// <param name="source">The source.</param>
              /// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
              private static void OnAutoGreyScaleImageIsEnabledPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
              {
                  var autoGreyScaleImg = source as AutoGreyableImage;
                  var isEnable = Convert.ToBoolean(args.NewValue);
                  if (autoGreyScaleImg != null)
                  {
                      if (!isEnable)
                      {
                          // Get the source bitmap
                          var bitmapImage = new BitmapImage(new Uri(autoGreyScaleImg.Source.ToString()));
                          // Convert it to Gray
                          autoGreyScaleImg.Source = new FormatConvertedBitmap(bitmapImage, PixelFormats.Gray32Float, null, 0);
                          // Create Opacity Mask for greyscale image as FormatConvertedBitmap does not keep transparency info
                          autoGreyScaleImg.OpacityMask = new ImageBrush(bitmapImage);
                      }
                      else
                      {
                          // Set the Source property to the original value.
                          autoGreyScaleImg.Source = ((FormatConvertedBitmap)autoGreyScaleImg.Source).Source;
                          // Reset the Opcity Mask
                          autoGreyScaleImg.OpacityMask = null;
                      }
                  }
              }
          }
      

      我希望这会帮助你和其他人来

      【讨论】:

        【解决方案3】:

        您使用的是什么操作系统? - WPF 看起来不如 XP 好(Vista 和 7 不是问题)。 我相信这是由于 XP 和较新的操作系统之间的抗锯齿默认设置不同。

        将 XAML 中的宽度和高度设置为 48 以匹配图像大小(同时检查拉伸参数)。

        使用 48x48 32 位 PNG,图像应该看起来不错。

        由于ribbon bar没有被拉伸,矢量图是多余的。

        如果上述方法没有帮助,请尝试设置align to device pixels 并设置LayoutRounding

        正如我在评论中建议的那样,您可以将图像调整为显示大小,但是,它应该在 XAML 中明确设置,以确保相同。

        您还可以通过将高度或宽度设置为 32 并使用 ScaleTransform 来让 WPF 显式调整图像大小。

        【讨论】:

        • 感谢您的回复,我会试试的。我使用的是 Windows 7。即使我的源图像是 48x48,我也不想在功能区上显示完整尺寸。这将占用太多空间,我只是不希望它们被正确调整大小。
        • 您是否尝试过对齐设备像素属性?
        • 我不知道投票否决,不是我……是的,我尝试了对齐设备像素,但没有任何效果……
        • 然后尝试 LayoutRounding(请参阅答案中的新链接)。
        • 恐怕 LayoutRounding 无法使用,因为我卡在框架 3.5 中...我开始怀疑这些设置是否仅与 Windows Aero 兼容?我的开发机器是虚拟机(公司政策),并且在这些机器上禁用了 Windows Aero。也许这可以解释为什么所有设置都不起作用?
        【解决方案4】:

        尝试使用vector graphics。您可以使用许多工具来生成与此类图像等效的 xaml,您可以查看article,它可能会有所帮助。

        【讨论】:

        • 可能是一个可能的解决方案,但 WPF 支持 PNG:s,您不需要将它们转换为矢量图形即可在功能区中使用它们。
        • @vanos 你的好友 WPF 支持 PNG。但问题是PNG能够在不被像素化的情况下缩小或扩大吗?如果您将矢量图形用作资源字典中的 XAML,您甚至可以在每次需要更小或更大的副本时重复使用这些图像而无需进行缩放。
        • 我希望 WPF 可以正确调整 PNG:s 的大小,因为使用 WinForms 这不是问题。在我的项目中,我有超过 100 张图像,所以我的最后一个选择是以某种方式操纵它们。
        • @vanos 我认为修复这 100 张图像将是最好的方法.. 只是一个建议。根据经验,找出问题的根源最能解决问题,而不是在每次出现新问题时都进行肮脏的工作。
        • 提前调整 100 张图像的大小比将它们重新绘制为矢量图形要容易得多! SVG 已经是矢量图形(不过,它们可以像 xaml 一样包含光栅格式)——本文无法帮助将 png 转换为矢量。
        猜你喜欢
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多