2

I have encountered a very odd problem today using WPF. Here is the code I have used to draw 10000 LineGeometry objects.

// Draw 10000 lines
var g = new GeometryGroup();
var x = 0;
var y = 0;
var n = 1;
while (n < 10000)
{
    x = x + 20;
    if (x > 600)
    {
        x = 0;
        y = y + 20;
    }
    var l = new LineGeometry
    {
        StartPoint = new Point(x, y),
        EndPoint = new Point(x, y + 15)
    };
    g.Children.Add(l);
    n++;
}

var drawing = new GeometryDrawing {Geometry = g};
var drawingGroup = new DrawingGroup();
drawingGroup.Children.Add(drawing);
var myPen = new Pen {Thickness = 1, Brush = Brushes.Yellow};
drawing.Pen = myPen;

var myImage = new Image {Stretch = Stretch.None, Margin = new Thickness(10)};
var myDrawingImage = new DrawingImage {Drawing = drawingGroup};

myImage.Source = myDrawingImage;
canvas.Children.Add(myImage);

Before EdgeMode.Aliased

Now as you can see the result is not crisp and I used the code below to achieve better results.

RenderOptions.SetEdgeMode(myImage, EdgeMode.Aliased);

The image gets crisp but has another side effects as you can see in the image below.

  1. Some lines are now shown.
  2. Some extra odd lines are shown.

After EdgeMode.Aliased

I have included the full code so you can experiment this for yourself.

Note: I'm using ZoomBorder class around the Canvas canvas. Pan & Zoom Image

Community
  • 1
  • 1
Vahid
  • 5,144
  • 13
  • 70
  • 146
  • If you let the loop run to 30000 lines the diagonal lines disappear :) – BlueM Mar 20 '14 at 17:48
  • 1
    Have you tried using RenderOptions.SetBitmapScalingMode(myImage, BitmapScalingMode.HighQuality); instead? – d.moncada Mar 20 '14 at 17:50
  • I can only confirm that running it without RenderingOptions produces a crisp output. Running it with RenderingOptions produces diagonal lines but still lines are all there for me. Feels like a bug in WPF aliasing to me. – BlueM Mar 20 '14 at 17:51
  • @BlueM Actually it seems that a Zoom class that I have is somehow messing with the image. I removed the class and everything seems ok! It is odd that this Zoom class doesn't interfere when I draw the `Line` objects as `Shape` but when I use `LineGeometry` the image gets messed up. – Vahid Mar 20 '14 at 18:05
  • @d.moncada I tested this and it totally solved the problem. Thanks. – Vahid Mar 20 '14 at 18:10
  • I don't use the zoom class and I get REALLY odd behavior. I will post it as answer. – BlueM Mar 20 '14 at 18:13
  • @BlueM Thanks. I would like to know the reason this happens. – Vahid Mar 20 '14 at 18:18
  • @Vahid sweet. Glad I could help, I added it as an answer so that is' more visible if anyone else comes across the same / similar need – d.moncada Mar 20 '14 at 18:21

2 Answers2

1

This is not a real answer but I want add something to that odd behavior of WPF in hope somebody can come up with a real explanation.

I added a single line from (0,0)-(20000,20000). Creating 8000 line objects (n < 8000) produces the expected result like this:

enter image description here

Now, creating 9000 line objects will totally mess it up, but see for yourself: enter image description here

Without setting EdgeMode.Aliased it looks fine, even with high counts of objects.

BlueM
  • 6,523
  • 1
  • 25
  • 30
  • I tried this and it gives me the correct results without ZoomBorder class. Are you sure that this gives you the above image? Maybe a variable is changed somewhere. I updated the question. – Vahid Mar 20 '14 at 18:29
  • Add this outside the loop: `g.Children.Add(new LineGeometry(new Point(0, 0), new Point(20000, 20000)));` and `RenderOptions.SetEdgeMode(myImage, EdgeMode.Aliased);` – BlueM Mar 20 '14 at 18:30
  • 1
    Wow, this must be a real bug with internal flags. It comes down as soon as we have 8193 objects added, it starts to get out of control. So there seems to be a limit of 8192 objects for it to be properly working. – BlueM Mar 20 '14 at 18:34
  • You are right! It does mess up the image, this is very odd actually. – Vahid Mar 20 '14 at 18:34
  • This is very alarming. I want to use WPF for a CAD program I'm developing and it even doesn't get such simple things right. – Vahid Mar 20 '14 at 18:37
1

Have you tried using

RenderOptions.SetBitmapScalingMode(myImage, BitmapScalingMode.HighQuality);

instead?

You can also set it on your Canvas control as well..

<Canvas RenderOptions.BitmapScalingMode="HighQuality"> ...
d.moncada
  • 16,900
  • 5
  • 53
  • 82
  • He said he solved it already but the question remains why `EdgeMode.Antialiased` shows that strange behavior. Also his first example without RenderingOptions shows clear crisp lines for me, obviously his Zoom class made problems. – BlueM Mar 20 '14 at 18:22
  • So we better don't mess with RenderOptions.SetEdgeMode :-) – BlueM Mar 20 '14 at 18:27
  • 1
    Yeah, usually in WPF, whenever I want to fix scaling / quality issues when it comes to Images, I use BitmapScalingMode and it seems to always solve the problem – d.moncada Mar 20 '14 at 18:31
  • Thanks. This solved it. But the problem remains when the above code is not used. – Vahid Mar 20 '14 at 18:32
  • Seems he encountered a real bug in WPF, as this problem starts as soon as more than 8192 objects are added into the GeometryGroup. – BlueM Mar 20 '14 at 18:38