2

ここでやっているのと同じように、デコレータのサブクラスで簡単な描画をしようとしています...

wpfで角が四角い境界線を描くにはどうすればよいですか?

...ただし、そこで使用している 2 つの境界線の太さではなく、1 ピクセルの境界線の太さを除きます。ただし、私が何をしても、WPF は「平滑化」を行う必要があると判断します (たとえば、単一ピクセルの線をレンダリングする代わりに、不透明度の約 50% の「半分」ごとに 2 ピクセルの線をレンダリングします)。言い換えれば、描画をアンチエイリアスしようとしています。アンチエイリアス描画はしたくありません。0,0 から 10,0 までの線を描画すると、スムージングなしで正確に 10 ピクセルの長さの単一ピクセル幅の線が得られると言いたいです。

WPFがそれを行うことはわかっていますが、それが特にSnapsToDevicePixelsとUseLayoutRoundingを導入した理由だと思いました。どちらもXAMLで「True」に設定しました。また、使用している数値が小数ではなく実際の整数であることを確認していますが、それでも、期待どおりのきれいで鮮明な 1 ピクセル幅の線が得られません。

ヘルプ!!!

マーク

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));

これが他の人に役立つことを願っています!

M

于 2011-04-11T20:38:53.680 に答える
1

この記事をご覧ください:物理デバイスのピクセルに正確に線を引く

UPD

リンクからの貴重な引用:

線がぼやけて見える理由は、点が線の端ではなく中心点であるためです。ペンの幅が 1 の場合、エッジは 2 ピクセルの間に正確に描画されます。

最初のアプローチは、各ポイントを整数値に丸め (論理ピクセルにスナップ)、ペン幅の半分のオフセットを与えることです。これにより、線のエッジが論理ピクセルに揃えられます。

幸いなことに、milcore (MIL は Media Integration Layer の略で、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 に答える