【问题标题】:GDI+ Rotate Gauge NeedleGDI+ 旋转量规针
【发布时间】:2015-02-20 06:14:49
【问题描述】:

更新 最终代码我必须根据以下答案使其工作:

public static byte[] Test(List<TestRange> ranges, int value)
        {
            var min = ranges.Min(t => t.MinValue);
            var max = ranges.Max(t => t.MaxValue);
            var rangeTotal = max - min;
            var valueAngle = ((((float)value-min) / (float)rangeTotal) * (float)270) + (float)135;
            using (var bmp = new Bitmap(500, 500))
            {
                using (var g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    var rec = new Rectangle(0, 0, 500, 500);
                    g.FillPie(new SolidBrush(Color.White), rec, 45, 90);
                    var startDeg = 135f;
                    foreach (var item in ranges.OrderBy(o => o.MinValue))
                    {
                        g.FillPie(new SolidBrush(ColorTranslator.FromHtml(item.Color)), rec, startDeg,
                            ((item.MaxValue - (float) item.MinValue)/rangeTotal)*270);
                        startDeg = startDeg + (((item.MaxValue - (float) item.MinValue)/rangeTotal)*270);
                    }
                    g.FillEllipse(new SolidBrush(Color.White), new Rectangle(100, 100, 300, 300));

                    using (var needle = Graphics.FromImage(bmp))
                    {
                        needle.TranslateTransform(250, 250);
                        needle.RotateTransform(valueAngle);
                        needle.TranslateTransform(-68, -39);
                        needle.DrawImage(Image.FromFile(@"C:\temp\needle.png"), new PointF(0,0));
                    }

                    g.FillRectangle(new SolidBrush(Color.Black), new RectangleF(new PointF(150,375), new SizeF(200,72)));
                    var sf = new StringFormat
                    {
                        Alignment = StringAlignment.Center,
                        LineAlignment = StringAlignment.Center
                    };
                    g.DrawString(value.ToString(), new Font(FontFamily.GenericSansSerif, 40), Brushes.White, new PointF(250, 415), sf);

                }
                using (var ms = new MemoryStream())
                {
                    bmp.Save(ms, ImageFormat.Png);
                    return ms.ToArray();
                }

            }
        }

我正在尝试制作自定义 GDI+ 仪表图。除了针旋转外,我一切正常。我已经阅读了尽可能多的文章,但无法弄清楚如何成功地做到这一点。我可以自己计算角度,但我需要从针图像中的一个点旋转针。 68px、39px(从左上角开始的 X、Y)。任何帮助,将不胜感激。代码如下:

public static void Test(List<TestRange> ranges, int value)
        {
            var min = ranges.Min(t => t.MinValue);
            var max = ranges.Max(t => t.MaxValue);
            var rangeTotal = max - min;
            using (var bmp = new Bitmap(500, 500))
            {
                using (var g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    var rec = new Rectangle(0, 0, 500, 500);
                    g.FillPie(new SolidBrush(Color.White), rec, 45, 90);
                    var startDeg = 135f;
                    foreach (var item in ranges.OrderBy(o => o.MinValue))
                    {
                        g.FillPie(new SolidBrush(ColorTranslator.FromHtml(item.Color)), rec, startDeg,
                            ((item.MaxValue - (float) item.MinValue)/rangeTotal)*270);
                        startDeg = startDeg + (((item.MaxValue - (float) item.MinValue)/rangeTotal)*270);
                    }
                    g.FillEllipse(new SolidBrush(Color.White), new Rectangle(100, 100, 300, 300));

                    //Needle logic
                    using (var needle = Graphics.FromImage(bmp))
                    {
                        //var m = new Matrix();
                        //m.RotateAt(180, new PointF(68,39));
                        //needle.Transform = m;
                        //needle.TranslateTransform(250, 250);
                        //needle.RotateTransform(180);
                        needle.DrawImage(Image.FromFile(@"C:\temp\needle.png"), new PointF(182, 211));
                    }

                    g.FillRectangle(new SolidBrush(Color.Black), new RectangleF(new PointF(150,375), new SizeF(200,72)));
                    var sf = new StringFormat
                    {
                        Alignment = StringAlignment.Center,
                        LineAlignment = StringAlignment.Center
                    };
                    g.DrawString(value.ToString(), new Font(FontFamily.GenericSansSerif, 40), Brushes.White, new PointF(250, 415), sf);

                }
                bmp.Save("C:\\temp\\Test.png", ImageFormat.Png);
            }
        }

这是它输出的图像:

这里是 needle.png 文件:

【问题讨论】:

  • “我已经阅读了尽可能多的文章”并没有告诉我们您的具体困难。你读过这个吗? stackoverflow.com/a/3809854 GDI Graphics 对象显然有一个 RotateTransform() 方法,您似乎没有使用它。
  • 如果我想旋转整个图像,那就太好了,但没有告诉我从图像中的固定点旋转图像中的图像。
  • 绘制旋转,然后调用 ResetTransform 以不影响绘图的其他部分。见Using a matrix to rotate rectangles individually
  • 图像是我上次检查的矩形。
  • 记住你是围绕0,0坐标旋转的。在-Image.Width/2, -Image.Height/2 处绘制您的图像,使用RotateTransformTranslateTransform 的组合首先将其旋转到所需的量,然后将其移动到仪表的中心。听起来您已将其旋转到图像的可见区域之外。

标签: c# gdi+


【解决方案1】:

诀窍是平移坐标系,使您想要的枢轴点位于原点,然后在 0,0 处绘制图像:

using (var needle = Graphics.FromImage(bmp))
{
    needle.TranslateTransform(182, 211);
    needle.RotateTransform(angle);
    needle.TranslateTransform(-68, -39);
    needle.DrawImage(Image.FromFile(@"C:\temp\needle.png"), new PointF(0, 0));
}

【讨论】:

  • 你从哪里得到 182、211?
  • 182、211 的位置来自您原始帖子中的代码。我认为那是您希望针的中心所在的位置。如果没有,只需将这些坐标替换为所需的中心即可。
  • 完美!谢谢!实际上是 250、250
【解决方案2】:

您需要将旋转与平移变换相结合,并在原点周围实际绘制图像。

public void DrawImageRotated(Graphics g, Image Image, Point Location, Single Angle)
{
    g.ResetTransform();
    g.RotateTransform(Angle);
    g.TranslateTransform(Location.X, Location.Y, Drawing2D.MatrixOrder.Append);
    g.DrawImageUnscaled(Image, -Image.Width / 2, -Image.Height / 2);
    g.ResetTransform();
}

【讨论】:

  • 感谢您的回答,这可行,但需要有点偏离中心。我在180度和210度测试。
  • 当我将对象移动到世界坐标时,我需要根据针的枢轴点将其居中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
  • 2016-12-10
  • 1970-01-01
  • 2017-04-11
  • 2014-09-10
  • 2014-07-11
  • 2011-01-17
相关资源
最近更新 更多