5

当我画这样的东西时(这里只是随机画):

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DrawingVisual visual = new DrawingVisual();
        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;
    }
}

DrawLine 和 DrawEllipse 的颜色混合。(我发现它只适用于使用笔的 DrawLine,而不是使用 Brush 的其他形式,如 Rectangle 和 Ellipse)。奇怪的是,即使使用来自底层网格背景 (argh) 的 LinearGradientBrush 的颜色。 我希望它们每个都具有完全不透明度的 z 顺序。

这里是 XAML 代码:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Image Name="image1" Stretch="None" />
</Window>

谢谢你的帮助。

4

4 回答 4

5

RenderTargetBitmap 有两个抗锯齿或子像素化问题:

1.

禁用位图本身的子像素化(例如,当它在 UIElement 中呈现时)。这可以通过应用解决:

    RenderOptions.SetBitmapScalingMode(image1, BitmapScalingMode.NearestNeighbor);

(其中 image1 是 WPF Image 对象)。

它仅支持 .NET 4 及更高版本。在您的特定情况下,这并不重要,因为线条是逐像素渲染的。

2.

渲染 INTO RenderTargetBitmap 时禁用子像素。可以通过RenderOptions.SetEdgeMode方法实现,参数值为EdgeMode.Aliased。

但是,此方法仅在以下情况下才有效:

  • 为 DrawingGroup 对象调用该方法。

  • 抗锯齿几何仅通过常规绘图复合嵌套(例如,如果 DrawingGroup 包含一个矩形,其中 VisualBrush 封装了一个 DrawingVisual,即使您使用该方法,该 DrawingVisual 的内容也将被抗锯齿)。

因此,您可以按如下方式重写代码:

    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;
于 2013-06-07T13:05:28.917 回答
2

您发布的代码是在彼此旁边绘制多条细线。它们中的每一个都经过抗锯齿处理,并且其侧面变得模糊。我想你描述的不透明度混合效果就是因为这个而发生的。

如果你画了一条粗线(即宽度为 10),效果就不会出现。

因此,解决方案取决于您要达到的目标:

  • 您可以尝试禁用抗锯齿,如果这令人满意,有关此的更多信息,请查看此处:禁用 WPF 图像上的抗锯齿
  • 用宽度更大的 Pen 画线,即new Pen(Brushes.Black, 2)
  • 在这种画线彼此靠近的特殊情况下,您可以将计数器增加 0.5f 而不是 1,因此请替换for (int i = 0; i <= 100 - 1; i++)for (float i = 0.0f; i <= 100 - 1; i+=0.5f).
  • 如果您不介意编写更多代码,则可以创建自己的自定义 Bitmap 类,该类不会使图像模糊。此处提供了一些解决方案http://www.nbdtech.com/Blog/archive/2008/11/20/blurred-images-in-wpf.aspx以及那里引用的站点
于 2012-06-12T17:17:09.190 回答
1

这里的另一种(更简单)方法:

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

对于您的示例,您只需要创建一个类,例如:

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

并用 AliasedDrawingVisual 替换您的 DrawingVisual 实例:

    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;
于 2013-06-07T15:26:02.823 回答
1

我在以编程方式渲染到DrawingContext. 唯一可行的方法是使用GuidelineSethttp ://wpftutorial.net/DrawOnPhysicalDevicePixels.html

于 2015-05-05T12:31:02.547 回答