Windows缩放超100%时WPF DrawingImage模糊裁切的解决咨询
问题描述
我有一个嵌入在WinForms的ElementHost容器中的WPF用户控件,控件包含图像、带图标按钮、标签等元素。我在资源字典中定义了几何图形资源,代码如下:
<Geometry x:Key="hlpGeometry">F0 M22,22z M0,0z M11,22C17.0751,22 22,17.0751 22,11 22,4.92487 17.0751,0 11,0 4.92487,0 0,4.92487 0,11 0,17.0751 4.92487,22 11,22z M12.1901,16.6889L10.2662,16.6889 10.2662,18.6998 12.1901,18.6998 12.1901,16.6889z M8.18758,5.59005C7.40125,6.43439,7.00808,7.55265,7.00808,8.94484L8.72898,8.94484C8.76121,8.10695 8.89334,7.46564 9.12537,7.02091 9.53787,6.2217 10.2823,5.82209 11.3587,5.82209 12.2288,5.82209 12.8508,6.05412 13.2246,6.51818 13.6049,6.98224 13.795,7.53009 13.795,8.16173 13.795,8.61291 13.6661,9.04797 13.4083,9.46691 13.2665,9.70539 13.0796,9.9342 12.8475,10.1533L12.0741,10.9171C11.3329,11.6454 10.8527,12.2932 10.6336,12.8604 10.4144,13.4211 10.3049,14.1623 10.3049,15.084L12.0258,15.084C12.0258,14.2719 12.116,13.6596 12.2965,13.2471 12.4834,12.8281 12.8862,12.319 13.505,11.7195 14.3557,10.8945 14.9197,10.2694 15.1969,9.84396 15.4804,9.41857 15.6222,8.86427 15.6222,8.18107 15.6222,7.05314 15.2387,6.12824 14.4718,5.40636 13.7112,4.67804 12.6961,4.31388 11.4263,4.31388 10.0535,4.31388 8.9739,4.73927 8.18758,5.59005z</Geometry> <DrawingGroup x:Key="hlpDrawingGroup" ClipGeometry="M0,0 V22 H22 V0 H0 Z"> <GeometryDrawing Brush="#FF00AA2B" Geometry="{StaticResource hlpGeometry}" /> </DrawingGroup> <DrawingImage x:Key="ico_helpDrawingImage" Drawing="{StaticResource hlpDrawingGroup}" />
将DrawingImage绑定到WPF的Image控件:
<Image x:Name="MyImage" Height="24" Width="24" VerticalAlignment="Center" Source="{Binding Path=MyIcon}"/>
Windows缩放比例为100%时显示正常,但设置为125%等大于100%的比例时,图像模糊且尺寸超出24x24出现裁切。需要解决让图像始终保持24x24尺寸且清晰的问题。
解决方案
1. 配置应用的DPI感知
在WinForms应用的app.config中添加以下配置,确保WPF控件能正确识别系统缩放比例:
<configuration> <appSettings> <add key="PresentationCore.DisableDpiAwareness" value="false" /> </appSettings> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware> </windowsSettings> </configuration>
也可以在应用启动时通过代码设置:
using System.Windows; using System.Windows.Media; using System.Windows.Forms; // 在应用初始化阶段执行 RenderOptions.ProcessRenderMode = RenderMode.Default; Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
2. 优化Image控件的渲染属性
给Image控件添加三个关键属性,强制高质量渲染并对齐像素:
<Image x:Name="MyImage" Height="24" Width="24" VerticalAlignment="Center" Source="{Binding Path=MyIcon}" RenderOptions.BitmapScalingMode="HighQuality" UseLayoutRounding="True" SnapsToDevicePixels="True"/>
BitmapScalingMode="HighQuality":启用高质量缩放算法,避免模糊UseLayoutRounding="True":确保元素尺寸对齐到设备像素边界SnapsToDevicePixels="True":强制渲染时严格对齐设备像素
3. 调整DrawingGroup的缩放适配
修改资源字典中的DrawingGroup,添加自适应DPI的缩放变换,确保几何图形能跟随系统缩放比例调整:
<DrawingGroup x:Key="hlpDrawingGroup" ClipGeometry="M0,0 V22 H22 V0 H0 Z"> <GeometryDrawing Brush="#FF00AA2B" Geometry="{StaticResource hlpGeometry}" /> <DrawingGroup.Transform> <ScaleTransform ScaleX="{Binding Source={x:Static SystemParameters.DpiScaleX}}" ScaleY="{Binding Source={x:Static SystemParameters.DpiScaleY}}" /> </DrawingGroup.Transform> </DrawingGroup>
4. 适配ElementHost的DPI行为
在ElementHost所在的WinForms窗体或控件中启用DPI适配:
// 在窗体构造函数中添加 this.AutoScaleMode = AutoScaleMode.Dpi;
同时处理ElementHost的DPI变化事件,手动更新WPF控件布局:
elementHost.DpiChanged += (s, e) => { if (elementHost.Child is FrameworkElement child) { child.InvalidateMeasure(); child.InvalidateArrange(); } };
内容的提问来源于stack exchange,提问作者Willy
相关产品推荐
相关产品推荐

