DrawingContext.DrawLine: Pen has no full opacity?

和自甴很熟 提交于 2019-12-04 10:09:48

There are two issues of antialiasing, or sub-pixeling, with RenderTargetBitmap:

1.

Disabling sub-pixeling for the bitmap itself (for example, when it is rendered within a UIElement). this is resolved by applying:

    RenderOptions.SetBitmapScalingMode(image1, BitmapScalingMode.NearestNeighbor);

(where image1 is the WPF Image object).

It is only supported for .NET 4 and above. In your specific case it doesn't matter as the lines are rendered pixel-after-pixel.

2.

Disabling sub-pixeling when rendering INTO the RenderTargetBitmap. It can be achieved by the method RenderOptions.SetEdgeMode with the parameter value of EdgeMode.Aliased.

HOWEVER, this method will work only if:

  • The method is called for a DrawingGroup object.

  • The antialiased geometry is nested only through regular drawing composite (for example, if the DrawingGroup contains a rectangle with a VisualBrush encapsulates a DrawingVisual, the content of that DrawingVisual will be antialiased even if you used that method).

Thus you can rewrite your code as follows:

    DrawingVisual visual = new DrawingVisual();
    DrawingGroup group = new DrawingGroup();

    Pen pen = new Pen(Brushes.Black, 1);

    group.Children.Add(new GeometryDrawing(Brushes.YellowGreen, pen, new EllipseGeometry(new Point(0,0), 40, 40)));

    for (int i = 0; i <= 100 - 1; i++)
      group.Children.Add(new GeometryDrawing(null, new Pen(Brushes.Black, 1), new LineGeometry(new Point(0, i), new Point(i, i))));

    RenderOptions.SetEdgeMode(group, EdgeMode.Aliased);

    DrawingContext context = visual.RenderOpen();
    context.DrawDrawing(group);
    context.Close();

    RenderTargetBitmap bmp = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);

    bmp.Render(visual);
    image1.Source = bmp;
Lukasz M

The code You posted is drawing mutliple thin lines next to each other. Each of them is antialiased and has got its sides blurred. I suppose the opacity mixing effect You described occurs because of this.

If you drew one thick line (i.e. with 10 width) the effect would not appear.

So, the solution depends on what exactly You are trying to achieve:

  • you can try to disable antialiasing, if this is satisfactory, for more information about this, take a look here: Disabling antialiasing on a WPF image
  • draw lines with a Pen that has got greater width, i.e. new Pen(Brushes.Black, 2)
  • in this particular case of drawing lines close to each other, you can increment the counter by 0.5f instead of 1, so replace for (int i = 0; i <= 100 - 1; i++) with for (float i = 0.0f; i <= 100 - 1; i+=0.5f).
  • if you don't mind writing some more code, you can create your own custom Bitmap class that doesn't make images blurry. Some solution is available here http://www.nbdtech.com/Blog/archive/2008/11/20/blurred-images-in-wpf.aspx and in the site referenced there
MaMazav

Another (easier) way here:

https://stackoverflow.com/a/10257614/2463642

For your example, you just have to create a class like:

    public class AliasedDrawingVisual : DrawingVisual
    {
        public AliasedDrawingVisual()
        {
            this.VisualEdgeMode = EdgeMode.Aliased;
        }
    }

and replace your DrawingVisual instance with AliasedDrawingVisual:

    DrawingVisual visual = new AliasedDrawingVisual(); // Here is the only change
    DrawingContext context = visual.RenderOpen();

    Pen pen = new Pen(Brushes.Black, 1);

    context.DrawEllipse(Brushes.YellowGreen, pen, new Point(0,0), 40, 40);

    for (int i = 0; i <= 100 - 1; i++)
      context.DrawLine(new Pen(Brushes.Black, 1), new Point(0, i), new Point(i, i));

    context.Close();

    RenderTargetBitmap bmp = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);

    bmp.Render(visual);
    image1.Source = bmp;

I have encountered the same issue with programmatic rendering to DrawingContext. The only only way that works is to use GuidelineSet: http://wpftutorial.net/DrawOnPhysicalDevicePixels.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!