2

我正在尝试在装饰器的子类中进行简单的绘图,类似于他们在这里所做的......

如何在 wpf 中绘制带有方角的边框?

...除了单像素边框厚度而不是他们在那里使用的两个。但是,无论我做什么,WPF 都决定它需要进行“平滑”(例如,它不是渲染单像素线,而是渲染两像素线,每个“一半”的不透明度约为 50%。)换句话说,它试图对绘图进行抗锯齿处理。我不想要抗锯齿绘图。我想说,如果我画一条从 0,0 到 10,0 的线,我会得到一条单像素宽的线,它的长度正好是 10 像素,没有经过平滑处理。

现在我知道 WPF 会这样做,但我认为这就是他们引入 SnapsToDevicePixels 和 UseLayoutRounding 的具体原因,我在 XAML 中将这两者都设置为“True”。我还确保我使用的数字是实际整数而不是小数,但我仍然没有得到我希望的漂亮、清晰、一个像素宽的线条。

帮助!!!

标记

4

2 回答 2

2

啊啊啊……明白了!WPF 认为从 0,0 到 10,0 的行实际上位于该逻辑行上,而不是 GDI 中的像素行。为了更好地解释,请考虑 WPF 中的坐标代表在一张方格纸上绘制的线条,而像素是这些线条组成的正方形(假设是 96 DPI。如果它们不同,则需要相应调整.)

所以......为了让绘图指向像素位置,我们需要将绘图从线条本身转移到像素的中心(方格纸上的正方形),所以我们将所有绘图移动 0.5、0.5(再次,假设 DPI 为 96)

因此,如果它是 96 DPI 设置,只需在 OnRender 方法中添加它就像一个魅力......

drawingContext.PushTransform(new TranslateTransform(.5, .5));

希望这对其他人有帮助!

于 2011-04-11T20:38:53.680 回答
1

看看这篇文章:在物理设备像素上精确地画线

UPD

链接中的一些有价值的报价:

线条看起来模糊的原因是我们的点是线条的中心点而不是边缘。笔宽为 1 时,边缘精确地绘制在两个像素之间。

第一种方法是将每个点四舍五入为一个整数值(捕捉到一个逻辑像素),并给它一个笔宽一半的偏移量。这确保了线的边缘与逻辑像素对齐。

幸运的是,milcore(MIL 代表媒体集成层,即 WPF 渲染引擎)的开发人员为我们提供了一种方法来指导渲染引擎在物理设备像素上精确地对齐逻辑坐标。为此,我们需要创建一个 GuidelineSet

protected override void OnRender(DrawingContext drawingContext)
{
    Pen pen = new Pen(Brushes.Black, 1);
    Rect rect = new Rect(20,20, 50, 60);

    double halfPenWidth = pen.Thickness / 2;

    // Create a guidelines set
    GuidelineSet guidelines = new GuidelineSet();
    guidelines.GuidelinesX.Add(rect.Left + halfPenWidth);
    guidelines.GuidelinesX.Add(rect.Right + halfPenWidth);
    guidelines.GuidelinesY.Add(rect.Top + halfPenWidth);
    guidelines.GuidelinesY.Add(rect.Bottom + halfPenWidth);

    drawingContext.PushGuidelineSet(guidelines);
    drawingContext.DrawRectangle(null, pen, rect);
    drawingContext.Pop();
}
于 2011-04-11T20:38:30.947 回答