如何将 C# Control 加上额外的文本保存到磁盘?
How to save C# Control plus extra text to disk?
我有一个 C# 程序,它是一个 控制台应用程序 ,但使用了来自 System.Windows.Forms.DataVisualization.Charting
的图表对象,而没有将 Chart
附加到Form
.
基本上我需要在 Chart
控件上生成一个圆环图,在圆环的中心打印一些文本,然后将图形和文本保存到磁盘上的文件中。
如果我在 PrePaint
事件中创建一个 TextAnnotation
,然后使用 DrawToBitmap
将图表保存到磁盘,覆盖的文本不会显示在磁盘上的文件中,即使我使用 Chart.Flush
和 Chart.Update
等的各种组合。据我所知,事件正在被触发并且 TextAnnotation
代码正在 运行.
另一方面,如果我根本不使用事件,而是从 Chart.CreateGraphics
获取一个 Graphics
对象,然后 Graphics.DrawString
打印文本,然后 Graphics.Flush
和Chart.DrawToBitmap
,还是没有显示文字。
我猜这是因为 Chart.DrawToBitmap
不知道用 Chart.CreateGraphics
绘制的额外内容,尽管我假设 Graphics.Flush
会处理这些。
保存图形和文本的最佳方式是什么?
编辑:按要求添加代码:
static void Main(string[] args)
{
String[] labels = { "Green", "Red", "Yellow", "Dark Red", "Blue" };
Color[] colours = { Color.Green, Color.Red, Color.Yellow, Color.DarkRed, Color.Blue };
Random rng = new Random();
Chart chart = new Chart();
chart.Size = new Size(320, 320);
ChartArea area = new ChartArea();
Series series = new Series();
chart.ChartAreas.Add(area);
series.ChartArea = area.Name;
series.ChartType = SeriesChartType.Doughnut;
series.IsValueShownAsLabel = true;
int total = 0;
for (int i = 0; i != labels.Length; i++)
{
int value = rng.Next(0, 50);
DataPoint p = new DataPoint(0, value);
total += value;
p.Color = colours[i];
p.Label = String.Empty;
p.Font = new Font("Microsoft Sans Serif", 10, FontStyle.Bold);
series.Points.Add(p);
}
series.Tag = total;
chart.Series.Add(series);
chart.Refresh();
using (Graphics g = chart.CreateGraphics())
{
String str = series.Tag.ToString();
Font font = new Font("Microsoft Sans Serif", 32, FontStyle.Bold);
SizeF strSize = g.MeasureString(str, font);
int strX = 100; int strY = 100;
g.DrawString(str, font, new SolidBrush(Color.Black), strX, strY);
g.DrawRectangle(new Pen(Color.Black), new Rectangle(strX, strY, (int)strSize.Width, (int)strSize.Height));
g.Flush();
}
String chartFilename = "chart.bmp";
String chartPath = Path.Combine("C:\Temp", chartFilename);
using (Bitmap bmp = new Bitmap(chart.Width, chart.Height))
{
chart.DrawToBitmap(bmp, chart.Bounds);
bmp.Save(chartPath);
}
System.Diagnostics.Process.Start("mspaint.exe", chartPath);
}
我怀疑图表在您的标签上方绘制。当您调用 DrawToBitmap 时,图表只会考虑它知道的视觉对象,而不是之后在顶部绘制的元素。
您需要颠倒绘图顺序。即
- 将图表绘制到位图中
- 将位图与预渲染图表放在一起,在顶部绘制标签
代码:
using (Bitmap bmp = new Bitmap(chart.Width, chart.Height))
{
chart.DrawToBitmap(bmp, chart.Bounds); // draw chart into bitmap first!
using (Graphics g = Graphics.FromImage(bmp)) // <--- new
{
// now draw label
String str = series.Tag.ToString();
Font font = new Font("Microsoft Sans Serif", 32, FontStyle.Bold);
SizeF strSize = g.MeasureString(str, font);
int strX = 100; int strY = 100;
g.DrawString(str, font, new SolidBrush(Color.Black), strX, strY);
g.DrawRectangle(new Pen(Color.Black), new Rectangle(strX, strY, (int)strSize.Width, (int)strSize.Height));
g.Flush();
}
bmp.Save(chartPath);
}
编辑:请务必在下面的评论中遵循 Jimi's 建议:
"reference System.Drawing.Imaging
, to have PixelFormat
and ImageFormat
available. At this moment, the image is saved as with a .bmp extension, while it's a .png file (the default)"
我有一个 C# 程序,它是一个 控制台应用程序 ,但使用了来自 System.Windows.Forms.DataVisualization.Charting
的图表对象,而没有将 Chart
附加到Form
.
基本上我需要在 Chart
控件上生成一个圆环图,在圆环的中心打印一些文本,然后将图形和文本保存到磁盘上的文件中。
如果我在 PrePaint
事件中创建一个 TextAnnotation
,然后使用 DrawToBitmap
将图表保存到磁盘,覆盖的文本不会显示在磁盘上的文件中,即使我使用 Chart.Flush
和 Chart.Update
等的各种组合。据我所知,事件正在被触发并且 TextAnnotation
代码正在 运行.
另一方面,如果我根本不使用事件,而是从 Chart.CreateGraphics
获取一个 Graphics
对象,然后 Graphics.DrawString
打印文本,然后 Graphics.Flush
和Chart.DrawToBitmap
,还是没有显示文字。
我猜这是因为 Chart.DrawToBitmap
不知道用 Chart.CreateGraphics
绘制的额外内容,尽管我假设 Graphics.Flush
会处理这些。
保存图形和文本的最佳方式是什么?
编辑:按要求添加代码:
static void Main(string[] args)
{
String[] labels = { "Green", "Red", "Yellow", "Dark Red", "Blue" };
Color[] colours = { Color.Green, Color.Red, Color.Yellow, Color.DarkRed, Color.Blue };
Random rng = new Random();
Chart chart = new Chart();
chart.Size = new Size(320, 320);
ChartArea area = new ChartArea();
Series series = new Series();
chart.ChartAreas.Add(area);
series.ChartArea = area.Name;
series.ChartType = SeriesChartType.Doughnut;
series.IsValueShownAsLabel = true;
int total = 0;
for (int i = 0; i != labels.Length; i++)
{
int value = rng.Next(0, 50);
DataPoint p = new DataPoint(0, value);
total += value;
p.Color = colours[i];
p.Label = String.Empty;
p.Font = new Font("Microsoft Sans Serif", 10, FontStyle.Bold);
series.Points.Add(p);
}
series.Tag = total;
chart.Series.Add(series);
chart.Refresh();
using (Graphics g = chart.CreateGraphics())
{
String str = series.Tag.ToString();
Font font = new Font("Microsoft Sans Serif", 32, FontStyle.Bold);
SizeF strSize = g.MeasureString(str, font);
int strX = 100; int strY = 100;
g.DrawString(str, font, new SolidBrush(Color.Black), strX, strY);
g.DrawRectangle(new Pen(Color.Black), new Rectangle(strX, strY, (int)strSize.Width, (int)strSize.Height));
g.Flush();
}
String chartFilename = "chart.bmp";
String chartPath = Path.Combine("C:\Temp", chartFilename);
using (Bitmap bmp = new Bitmap(chart.Width, chart.Height))
{
chart.DrawToBitmap(bmp, chart.Bounds);
bmp.Save(chartPath);
}
System.Diagnostics.Process.Start("mspaint.exe", chartPath);
}
我怀疑图表在您的标签上方绘制。当您调用 DrawToBitmap 时,图表只会考虑它知道的视觉对象,而不是之后在顶部绘制的元素。
您需要颠倒绘图顺序。即
- 将图表绘制到位图中
- 将位图与预渲染图表放在一起,在顶部绘制标签
代码:
using (Bitmap bmp = new Bitmap(chart.Width, chart.Height))
{
chart.DrawToBitmap(bmp, chart.Bounds); // draw chart into bitmap first!
using (Graphics g = Graphics.FromImage(bmp)) // <--- new
{
// now draw label
String str = series.Tag.ToString();
Font font = new Font("Microsoft Sans Serif", 32, FontStyle.Bold);
SizeF strSize = g.MeasureString(str, font);
int strX = 100; int strY = 100;
g.DrawString(str, font, new SolidBrush(Color.Black), strX, strY);
g.DrawRectangle(new Pen(Color.Black), new Rectangle(strX, strY, (int)strSize.Width, (int)strSize.Height));
g.Flush();
}
bmp.Save(chartPath);
}
编辑:请务必在下面的评论中遵循 Jimi's 建议:
"reference
System.Drawing.Imaging
, to havePixelFormat
andImageFormat
available. At this moment, the image is saved as with a .bmp extension, while it's a .png file (the default)"