提高我的C#位图

时间:2016-04-12 21:07:57

标签: c# image winforms bitmap

我使用位图在WinForm中创建自定义图像。我有一个代表桁架的类,想要想象它。现在这是我绘制桁架的代码:

    public void DrawAnsComponent()
    {
        Pen pen = new Pen(Color.Black);
        maxWidth = 0;
        maxHeight = 0;
        //Getting size of bitmap
        foreach (AnsJoint joint in this.AnsToShow.AnsJoints)
        {
            if (joint.Location.X.Length > maxWidth)
            {
                maxWidth = (int)joint.Location.X.Length;
            }
            if (joint.Location.Y.Length > maxHeight)
            {
                maxHeight = (int)joint.Location.Y.Length;
            }
        }
        maxHeight += 55; maxWidth += 5;
        Bitmap bm = new Bitmap(maxWidth, maxHeight); //Creating Bitmap
        gr = Graphics.FromImage(bm); //Creating graphic to project onto bitmap
        gr.SmoothingMode = SmoothingMode.HighQuality;
        foreach (AnsJoint joint in this.AnsToShow.AnsJoints)
        {
            PointF jointPoint = this.ToCartesian(new PointF((float)joint.Location.X.Length - 4f, (float)joint.Location.Y.Length + 10f), maxHeight);
            gr.DrawString(joint.JointID.ToString(), new Font(FontFamily.GenericMonospace, 6f, FontStyle.Regular, GraphicsUnit.Point, 1, false), Brushes.Black, jointPoint);
        }
        foreach (AnsMember member in this.AnsToShow.AnsMembers) //Drawing each member
        {
            List<AnsPanel> panels = member.Panels; //Drawing the panels

            foreach (AnsPanel pan in panels)
            {
                pen.Color = Color.Red;
                PointF p1 = this.ToCartesian(new PointF((float)pan.I.Location.X.Length, (float)pan.I.Location.Y.Length), maxHeight);
                PointF p2 = this.ToCartesian(new PointF((float)pan.J.Location.X.Length, (float)pan.J.Location.Y.Length), maxHeight);

                gr.DrawEllipse(pen, p1.X - 2.5f, p1.Y - 2.5f, 5, 5);
                gr.DrawEllipse(pen, p2.X - 2.5f, p2.Y - 2.5f, 5, 5);
                /*
                gr.DrawEllipse(pen, p1.X - 3, p1.Y - 3.3f, 5, 5);
                gr.DrawEllipse(pen, p2.X - 3, p2.Y - 3.3f, 5, 5);
                pen.Color = Color.Black;
                gr.DrawLine(pen, p1, p2);
                */
            }
            List<AnsLink> links = member.Links; //Drawing the links
            foreach (AnsLink link in links)
            {
                PointF p1 = this.ToCartesian(new PointF((float)link.I.Location.X.Length, (float)link.I.Location.Y.Length), maxHeight);
                PointF p2 = this.ToCartesian(new PointF((float)link.J.Location.X.Length, (float)link.J.Location.Y.Length), maxHeight);
                gr.FillEllipse(Brushes.Green, p1.X - 1.5f, p1.Y - 1.5f, 3, 3);
                gr.FillEllipse(Brushes.Green, p2.X - 1.5f, p2.Y - 1.5f, 3, 3);
                gr.DrawLine(pen, p1, p2);
            }
        }
        pictureBox1.Image = bm;

    public PointF ToCartesian(PointF p, int maxHeight)
    {
        return new PointF(p.X, (p.Y - (maxHeight * .8f)) * -1);
    }

这是结果

enter image description here

所以它的工作非常精细,除了像素化让它看起来像一张质量非常低的画面。有什么我可以改变我的代码,以使图像更高的质量?

2 个答案:

答案 0 :(得分:1)

PictureBox只是缩放您在Bitmap中绘制的小图片。您显然是根据尺寸确定绘图的大小(以像素为单位),现实世界&#34;坐标,你的桁架。相反,您可以在计算几何体的屏幕坐标时应用比例因子,以便绘图填充控件的可见空间。但是,如果您这样做,我建议放弃Bitmap,而是直接在其PictureBox事件处理程序中的Paint上绘制(或者派生自定义控件并将绘图放入受保护的OnPaint方法)。这样你就不必处理Bitmap的大小与PictureBox的大小同步,这将是一个真正的麻烦,而不是提到效率低下。基本上你不希望PictureBox试图调整图像的大小,因为它会给你提供你在缩小时看到的那种模糊性以及缩小时的怪异效果。

希望这很清楚,信息量足以让你入门。

答案 1 :(得分:0)

两个想法:

1)Graphics对象上还有一些您想要玩的其他属性,包括SmoothingModeInterpolationMode

Graphics.SmoothingMode = SmoothingMode.AntiAlias
Graphics.InterpolationMode = InterpolationMode.Bicubic

2)您可能使位图比实际需要的要小得多。允许您在不明显更改代码的情况下使位图更大的一个想法是使用缩放因子,例如

var scale = 2;
Bitmap bm = new Bitmap(maxWidth * scale, maxHeight * scale); //Creating Bitmap
using (var gr = Graphics.FromImage(bm)) //Creating graphic to project onto bitmap
{
  gr.Transform.Scale(scale, scale)
  // continue as before
}

另外,不要忘记丢弃一次性对象(例如Graphics对象)。在此示例中,using关键字会为您处理。