DrawingContext.DrawLine:Pen没有完全不透明度?

Jul*_*ian 5 wpf transparency z-order opacity drawingcontext

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

DrawLine和DrawEllipse混合的颜色.(我发现只有DrawLine才使用笔,而不是像Rectangle和Ellipse这样使用Brush的其他形式).奇怪的是,即使是基础网格背景(argh)的LinearGradientBrush的颜色. 我希望它们是z-Ordered,每个都具有完全不透明度.

这里是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>
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

MaM*_*zav 5

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

1.

禁用位图本身的子像素化(例如,在UIElement中呈现时).通过申请解决这个问题:

    RenderOptions.SetBitmapScalingMode(image1, BitmapScalingMode.NearestNeighbor);
Run Code Online (Sandbox Code Playgroud)

(其中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;
Run Code Online (Sandbox Code Playgroud)


Luk*_*z M 2

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

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

因此,解决方案取决于您到底想要实现什么目标:

  • 您可以尝试禁用抗锯齿,如果这令人满意,有关这方面的更多信息,请查看此处:Disabling antialiasing on a WPF image
  • 用宽度更大的笔画线,即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以及那里引用的站点