How can I avoid anti-aliasing using WPF?

One of the big problems with WPF is anti-aliasing. Actually, why UseLayoutRending was introduced in WPF 4.0. However, this does not work for me in the following example:

<StackPanel UseLayoutRounding="True" TextOptions.TextFormattingMode="Display" > <Line X1="0" Y1="0" X2="200" Y2="0" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line> <Line X1="0" Y1="1.5" X2="200" Y2="1.5" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line> <Line X1="0" Y1="3.5" X2="200" Y2="3.5" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line> <Line X1="0" Y1="7" X2="200" Y2="7" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line> <Line X1="0" Y1="9" X2="200" Y2="9" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line> </StackPanel> 

The last two lines are still blurry. (I am using Windows 7)

Any solution?

Or is it a bug in WPF 4.0 beta?

+4
source share
4 answers

Floele's answer showed the right direction, but the answer was incomplete. Just set y values ​​to half a pixel, for example. Y1 = "7" β†’ Y1 = "7.5"

For this reason, the second and third lines are not blurred.

+2
source

Getting strings that look sharp in WPF can be quite complicated! And a few times ... it seems like a little black magic is needed!

I think the answers to the paired and kimki are pointing in the right direction. That is, often you want to place single pixel lines on a border of 0.5 pixels ... given the way it draws a line (half on one side and half on the other).

However, this is not always so simple. For example, it also depends on the surrounding xaml . For example, try executing this code and resize it:

 <Canvas HorizontalAlignment="Center" VerticalAlignment="Center"> <Line X1="0" Y1="5" X2="200" Y2="5" StrokeThickness="1" Stroke="Black" UseLayoutRounding="True"/> <Line X1="0" Y1="15" X2="200" Y2="15" StrokeThickness="1" Stroke="Black" UseLayoutRounding="True"/> </Canvas> 

Then try this code (again, resize when you do this):

 <Canvas HorizontalAlignment="Center" VerticalAlignment="Center" UseLayoutRounding="True"> <Line X1="0" Y1="5" X2="200" Y2="5" StrokeThickness="1" Stroke="Black"/> <Line X1="0" Y1="15" X2="200" Y2="15" StrokeThickness="1" Stroke="Black"/> </Canvas> 

The only difference between the two fragments is that the first uses UseLayoutRounding on the lines, and the second uses UseLayoutRounding in the Canvas container (which then also inherits the properties of the lines).

However, this difference gives some interesting results. When UseLayoutRounding is used on a container, single pixel lines constantly remain scattered over 2 pixels and they do not move. When UseLayoutRounding is used directly on the lines, and you resize, the lines will sometimes have 1 pixel of sharpness ... and other times will be speada by 2 pixels.

And that leads me to the xaml pattern in the original question. A few comments about this:

  • First, you must understand that the UseLayoutRounding and SnapsToDevicePixels properties are inherited. That is, if you use it in the layout container, it inherits the elements in the layout container.
  • UseLayoutRounding and SnapsToDevicePixels do not have to be used together. They may be ... but I usually try to use them separately ... either one or the other. More info here: When should I use SnapsToDevicePixels in WPF 4.0?
  • The TextOptions.TextFormattingMode parameters affect the text, not the lines.
  • This StackPanel, which you use as the layout container, can also affect how the lines are drawn. Canvas allows you to more accurately control the positioning of your lines. A StackPanel will simply place one line after another line ... and may produce unexpected results.

More information than the original poster would have liked. However, I personally know how difficult it is to use lines in WPF. Hope this info helps someone!

+2
source

The reason seems to be simpler. I just found an explanation in "Pro WPF in VB 2010" and not on MSDN: http://books.google.de/books?id=F-gMZkAlUDUC&pg=PA334&lpg=PA334

In short, StrokeThickness will be split on both sides of the shape, so a StrokeThickness of 1 is equal to 0.5 thickness for each side, and since the line has only one side, it will be 0.5 thick units and therefore appear blurry even when using SnapsToDevicePixels=True . So just use "2" as StrokeThickness.

You can verify this using the StrokeThickness of 4, the line will have a thickness of 2, which is more than a β€œclosed” single pole deviation.

+1
source

Have you tried changing the TextOptions.TextFormattingMode property to Display ? See this post from Lester Lobo for more details.

0
source

All Articles