GDI+ 旋转量针
GDI+ Rotate Gauge Needle
更新
我必须根据以下答案使其工作的最终代码:
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+ 规格表。除了针旋转外,我一切正常。我已经阅读了尽可能多的文章,但无法弄清楚如何成功地做到这一点。我可以自己计算角度,但我需要从针图像中的一个点旋转针。 68 像素、39 像素(从左上角开始的 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 文件:
您需要将旋转与平移变换相结合,并实际围绕原点绘制图像。
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();
}
诀窍是平移坐标系,使您想要的轴心点位于原点,然后在 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));
}
更新 我必须根据以下答案使其工作的最终代码:
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+ 规格表。除了针旋转外,我一切正常。我已经阅读了尽可能多的文章,但无法弄清楚如何成功地做到这一点。我可以自己计算角度,但我需要从针图像中的一个点旋转针。 68 像素、39 像素(从左上角开始的 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 文件:
您需要将旋转与平移变换相结合,并实际围绕原点绘制图像。
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();
}
诀窍是平移坐标系,使您想要的轴心点位于原点,然后在 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));
}