首页 > 解决方案 > WPF:绘图上下文分辨率

问题描述

我正在使用DrawingContext类来绘制条形图,但生成的标签和刻度是模糊的:

在此处输入图像描述

在代码中,我使用了一个BarRenderer派生自FrameworkElement. 每个条都由一个BarRenderer实例表示,我通过覆盖该OnRender方法进行绘图。每个“条”都有一个label和一个下面的文本并value定义条的高度。而负责绘制label和tick的逻辑如下:labelvalue

private void DrawLabel(DrawingContext drawingContext, FormattedText text, double x, double y, int direction)
{
    drawingContext.DrawLine(_blackPen, new Point(Width * 0.5, y), new Point(Width * 0.5, y + 6));

    y += 6;
    if (LabelRotationDegree != 0)
    {
        RotateTransform rotateTransform = new RotateTransform(-LabelRotationDegree, 0.5 * Width, y + text.Height * 0.5);
        TranslateTransform translateTransform = new TranslateTransform(0, direction * text.WidthIncludingTrailingWhitespace * 0.5);

        drawingContext.PushTransform(translateTransform);
        drawingContext.PushTransform(rotateTransform);
    }

    drawingContext.DrawText(text, new Point(x, y));

    if (LabelRotationDegree != 0)
    {
        drawingContext.Pop();
        drawingContext.Pop();
    }
}

我怀疑问题出在旋转变换上,因为当标签没有被变换时,它们不再像以前那样模糊:

在此处输入图像描述

但可以看出,一些蜱比其他蜱更暗。那么我做错了什么?

编辑:

我已经设置SnapsToDevicePixelstrue,当我设置为时RenderOptions.SetEdgeModeAliased一些刻度消失并且文字仍然模糊:

在此处输入图像描述

编辑 2:更多代码

public class GraphUnitRenderer : FrameworkElement
{
    private const double TEXT_SIZE = 12;
    private const double KEY_LABELS_HEIGHT = 50;

    private readonly Typeface _typeface;
    private readonly CultureInfo _cultureInfo;
    private readonly Pen _blackPen;
    private readonly Pen _bluePen;
    private readonly Pen _tickBlackPen;
    private readonly Pen _whitePen;



    public BarData Data { get; set; }

    //Some properties

    public GraphUnitRenderer()
    {
        _typeface = new Typeface("Segoe UI");
        _cultureInfo = CultureInfo.CurrentCulture;

        _blackPen = new Pen(Brushes.Black, 1);
        _bluePen = new Pen(Brushes.Blue, 1);
        _tickBlackPen = new Pen(Brushes.Black, 2);
        _whitePen = new Pen(Brushes.White, 1);

        /*
        _blackPen.Freeze();
        _bluePen.Freeze();
        _tickBlackPen.Freeze();
        _whitePen.Freeze();
        */

        RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);
        SnapsToDevicePixels = true;

    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);


        FormattedText keyText = GetText(Data.Key);

        //Bar drawing logic 

        if (LabelDisplayIsForced || (LabelRotationDegree == 0 && keyText.WidthIncludingTrailingWhitespace < Width) || (LabelRotationDegree != 0 && keyText.Height < Width))
            DrawLabel(drawingContext, keyText, 0.5 * (Width - keyText.WidthIncludingTrailingWhitespace), GetYPosition(1) + 1, 1);

    }


    private void DrawLabel(DrawingContext drawingContext, FormattedText text, double x, double y, int direction)
    {
        drawingContext.DrawLine(_blackPen, new Point(Width * 0.5, y), new Point(Width * 0.5, y + 6));

        y += 6;
        if (LabelRotationDegree != 0)
        {
            RotateTransform rotateTransform = new RotateTransform(-LabelRotationDegree, 0.5 * Width, y + text.Height * 0.5);
            TranslateTransform translateTransform = new TranslateTransform(0, direction * text.WidthIncludingTrailingWhitespace * 0.5);

            drawingContext.PushTransform(translateTransform);
            drawingContext.PushTransform(rotateTransform);
        }

        drawingContext.DrawText(text, new Point(x, y));

        if (LabelRotationDegree != 0)
        {
            drawingContext.Pop();
            drawingContext.Pop();
        }
    }


    private double GetYPosition(double position) => Height - position - KEY_LABELS_HEIGHT;
    private FormattedText GetText(string text) => new FormattedText(text, _cultureInfo, FlowDirection.LeftToRight, _typeface, TEXT_SIZE, Brushes.Black, VisualTreeHelper.GetDpi(this).PixelsPerDip);
}

标签: wpfrenderingdrawingcontext

解决方案


推荐阅读