WPF 旋转元素的抗锯齿边缘

WPF Anti-aliasing edge of turned elements

我比平时更需要 Anti-alias 旋转矩形的边缘。

我的代码是这样的:

    <Rectangle Margin="20,20,147,135" Fill="#FFCAD2DE" RenderOptions.EdgeMode="Unspecified">
        <Rectangle.Effect>
            <DropShadowEffect BlurRadius="4" ShadowDepth="2" Opacity=".5"/>
        </Rectangle.Effect>
        <Rectangle.RenderTransform>
            <RotateTransform CenterX="0" CenterY="0" Angle="6" />
        </Rectangle.RenderTransform>
    </Rectangle>

我以编程方式慢慢改变角度...

但是结果在某些角度出现了锯齿,如下图(左侧)。我希望矩形的边缘在所有角度都完全平滑,如下图(右侧)。


编辑 1:

我使用.NET 3.5

看起来这不可能:RotateTranform causes alias edges on border control or a Rectangle.

从那里开始:

Fortunately, the edge becomes perfectly soomth for 25+ degree rotations on my computer. If you eventually find a way to solve your problem, please share with us. It will be very beneficial for other community members having the similar questions.

以下步骤可以提供帮助


A)

首先,我将我的项目从 .NET 3.5 移动到 .Net 4.5,没有进行任何更改,结果是:

It looks like very smoother


B)

Layout Rounding:

What is Layout Rounding and how to use it in WPF 4

When an object edge falls in the middle of a pixel device, the DPI-independent graphics system can create rendering artifacts, such as blurry or semi-transparent edges.

Previous versions of WPF included pixel snapping to help handle this case. Silverlight 2 introduced layout rounding, which is another way to move elements so that edges fall on whole pixel boundaries.

WPF now supports layout rounding with the UseLayoutRounding attached property on FrameworkElement. Drawing objects on pixel boundaries eliminates the semi-transparent edges that are produced by anti-aliasing, when an edge falls in the middle of a device pixel. When you use layout rounding, the layout system creates small variations in the column or row measurements to avoid sub-pixel rendering.

以下代码使用 UseLayoutRounding 附加 属性 设置在单个像素宽度线上。当您缓慢调整 window 大小时,您可以看到布局舍入所产生的差异。

<StackPanel Width="150" Margin="7" Orientation="Horizontal">
  <!-- Single pixel line with layout rounding turned OFF.-->
  <Rectangle UseLayoutRounding="False" Width="45.6" Margin="10" Height="1" Fill="Red"/>

  <!-- Single pixel line with layout rounding turned ON.-->
  <Rectangle UseLayoutRounding="True" Width="45.6" Margin="10" Height="1" Fill="Red"/>
</StackPanel> 


C)

SnapsToDevicePixels

Note

You should set UseLayoutRounding to true on the root element. The layout system adds child coordinates to the parent coordinates; therefore, if the parent coordinates are not on a pixel boundary, the child coordinates are also not on a pixel boundary.

If UseLayoutRounding cannot be set at the root, set SnapsToDevicePixels on the child to obtain the effect that you want.