弧形图形质量 [英] Arc graphic quality

查看:313
本文介绍了弧形图形质量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

回到这里.有什么方法可以提高电弧的质量吗?
我正在使用e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

Back here. Is there any way to improve the quality of the Arc?
I'm using e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

这是创建圆弧的代码:

using (GraphicsPath gp = new GraphicsPath())
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    gp.Reset();
    gp.AddPie(_OuterRectangle, (float)_Properties.Origin, (float)_Properties.GaugeType);
    gp.Reverse();

    gp.AddPie(_InnerRectangle, (float)_Properties.Origin, (float)_Properties.GaugeType);
    gp.Reverse();
    pArea.SetClip(gp);

    using (Pen oPen = new Pen(this.ForeColor, 2f))
    {
       e.Graphics.DrawPath(oPen, gp);
    }
    e.Graphics.SetClip(ClientRectangle);
}

谢谢.


我做了LarsTech提出的建议,现在质量很完美,但是我没有所需的身材:


I've did what LarsTech proposed and now the quality is perfect, but I'm not having the figure I need:

  • OuterRectangle :是ClientRectangle区域,我正在对其进行操作以使Width和Height的长度相同;
  • InnerRectangle :是OuterRectangle的ClientRectangle区域ergo的2/3;
  • 属性.来源:是圆弧开始的角度.我在枚举器中将其作为基数,北为270,东为0,
    所以.如果是数字,则为西南,为135度;

  • OuterRectangle: is the ClientRectangle area, that I'm manipulating it to make Width and Height the same lenght;
  • InnerRectangle: is 2/3ths of the ClientRectangle area, ergo, of the OuterRectangle;
  • Properties.Origin: is the angle where the arc starts. I have it in an enumerator as Cardinal Points, where North is 270, East is 0,
    and so. In case of the figure, is SouthWest, 135 degrees;

Properties.GaugeType :是另一个枚举器,它表示是否Complete = 360,Half = 180,Quarter = 90,这样我就可以确定扫角.如果数字是ThreeQuarter,则为270度.

Properties.GaugeType: is another enumerator that says if is Complete = 360, Half = 180, Quarter = 90, so with that I can determine the sweep angle. In case of the figure is ThreeQuarter, 270 degrees.

推荐答案

问题:
裁剪当前图形的区域时( Graphics.SetClip 方法),由于 Graphics.SmoothingMode = SmoothingMode.AntiAlias 产生的抗锯齿效果消失了,因此,最终的图形质量也会下降.

The problem:
When clipping a region of the current Graphics (Graphics.SetClip method), the resulting drawing loses quality, because the antialiasing effect generated by Graphics.SmoothingMode = SmoothingMode.AntiAlias is lost.

一种可能的解决方案是避免剪切由用于设计弧的GraphicsPath定义的区域(

A possible solution is to avoid clipping the region defined by the GraphicsPath used to design the arcs (GraphicsPath.AddPie method); this, however, leaves the lines of the Pie visible, compromising the shape.

另一种解决方案是使用画布"的背景色在圆弧的中心绘制一个省略号.由于弧线是使用两个矩形绘制的,因此我们可以使用内部矩形将其充气( Rectangle.Inflate 方法)(通常是用于ouline的Pen大小的一部分-Pen.Width / 2-).

Another solution is to draw an ellipsis in the center of the arcs using the background color of the Canvas. Since the arcs are drawn using two rectangles, we can use the inner rectagle, inflate it (Rectangle.Inflate method) as needed (a fraction - Pen.Width / 2 - of the Pen size used for the ouline, usually).

这允许删除由GraphicsPath形状生成的伪像,并在形状的中心绘制一些其他图形内容.

This allows to delete the artifacts generated by the GraphicsPath shapes and to draw some other graphics content in the center of the shapes.

例如,使用不同的画笔:

For example, using different Brushes:

  LinearGradientBrush           HatchBrush               TextureBrush

当然,还有其他方法可以达到相同的结果.我们可以使用 GraphicsPath.AddArc绘制圆弧方法,提取或计算弧的第一个点和最后一个点,并用它们绘制两条线(

Of course there are other methods to achieve the same result. We could draw the Arcs using the GraphicsPath.AddArc method, extract or calculate the first and last points of the Arcs and use them to draw two lines (GraphicsPath.AddLine) that will close the figures.

但是,由于我们要在圆弧的中心绘制不同的图形对象,因此这些对象将始终覆盖中心区域.

But, since we want to draw different graphics objects in the center of the arcs, these objects will cover the center area anyway.

如何使用此代码:

  • 在表单中,添加一个 TrackBar (在此处称为 tbarSpeed )
  • 添加尺寸为(200, 200)面板(称为 Canvas ).使用此处提供的自定义面板"控件,该控件在其构造函数中添加了一些ControlStyles.这样可以避免闪烁和伪影
  • 连接TrackBar tbarSpeed_Scroll 事件和面板 Canvas_Paint 事件.
  • In a Form, add a TrackBar (called tbarSpeed, here)
  • Add a Panel (called Canvas), with Size (200, 200). Use the Custom Panel control provided here, which adds some ControlStyles in its costructor. This will avoid flickering and artifacts
  • Wire up the TrackBar tbarSpeed_Scroll event and the Panel Canvas_Paint event.
using System.Drawing;
using System.Drawing.Drawing2D;


float GaugeValue = 88.0f;
float GaugeSweepAngle = 270.0f;
float GaugeStartAngle = 135.0F;

private void Canvas_Paint(object sender, PaintEventArgs e)
{
    Control canvas = sender as Control;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    Rectangle outerRectangle = new Rectangle(10, 10, 180, 180);
    Rectangle innerRectangle = new Rectangle(30, 30, 140, 140);
    Rectangle blendRectangle = new Rectangle(10, 10, 180, 160);
    PointF innerCenter = new PointF(outerRectangle.Left + (outerRectangle.Width / 2),
                                    outerRectangle.Top + (outerRectangle.Height / 2));
    float gaugeLength = (outerRectangle.Width / 2) - 2;

    using (GraphicsPath path = new GraphicsPath())
    {
        path.AddPie(outerRectangle, GaugeStartAngle, GaugeSweepAngle);
        path.AddPie(innerRectangle, GaugeStartAngle, GaugeSweepAngle);
        innerRectangle.Inflate(-1, -1);

        using (Pen pen = new Pen(Color.White, 3f))
        using (SolidBrush backgroundbrush = new SolidBrush(canvas.BackColor))
        using (LinearGradientBrush gradientBrush = new LinearGradientBrush(blendRectangle,
               Color.Green, Color.Red, LinearGradientMode.ForwardDiagonal))
        {
            Blend blend = new Blend()
            {
                Factors = new[] { 0.0f, 0.0f, 0.1f, 0.3f, 0.7f, 1.0f },
                Positions = new[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f }
            };

            gradientBrush.Blend = blend;
            e.Graphics.FillPath(gradientBrush, path);
            e.Graphics.DrawPath(pen, path);

            e.Graphics.FillEllipse(backgroundbrush, innerRectangle);

            using (StringFormat format = new StringFormat())
            {
                format.Alignment = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;
                innerRectangle.Location = new Point(innerRectangle.X, innerRectangle.Y + canvas.Font.Height);
                e.Graphics.DrawString(GaugeValue.ToString() + "%", canvas.Font, Brushes.White, innerRectangle, format);
            }

            using (Matrix matrix = new Matrix())
            {
                matrix.RotateAt(GaugeStartAngle + 90 + (GaugeValue * (GaugeSweepAngle / 100)), innerCenter);
                e.Graphics.Transform = matrix;
                e.Graphics.DrawLine(pen, innerCenter, new PointF(innerCenter.X, innerCenter.Y - gaugeLength));
                e.Graphics.ResetTransform();
            }
        }
    }
}

private void tbarSpeed_Scroll(object sender, EventArgs e)
{
    GaugeValue = tbarSpeed.Value;
    Canvas.Invalidate();
}

自定义面板控件:

using System.ComponentModel;
using System.Windows.Forms;

[DesignerCategory("code")]
public class DrawingPanel : Panel
{
    public DrawingPanel()
    {
        this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                      ControlStyles.UserPaint |
                      ControlStyles.OptimizedDoubleBuffer, true);
        this.UpdateStyles();
    }
}

PasteBin上的示例代码

这篇关于弧形图形质量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆