首页 > 解决方案 > 如何将 C# 控件和额外的文本保存到磁盘?

问题描述

我有一个 C# 程序,它是一个控制台应用程序,但使用了来自 的 Chart 对象System.Windows.Forms.DataVisualization.Charting,而没有附加ChartForm.

基本上我需要在Chart控件上生成一个甜甜圈图,在甜甜圈的中心打印一些文本,然后将图形和文本保存到磁盘上的文件中。

TextAnnotation如果我在事件中创建一个PrePaint,然后使用 将图表保存到DrawToBitmap磁盘,即使我使用 和 的各种组合等,覆盖的文本也不会显示在磁盘上的文件中。据Chart.FlushChart.Update所知,事件正在被触发并且TextAnnotation代码正在运行。

另一方面,如果我根本不使用事件,而是Graphics从 , 获取一个对象Chart.CreateGraphics,然后Graphics.DrawString打印文本,然后Graphics.FlushChart.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);
}

标签: c#.netmicrosoft-chart-controls

解决方案


我怀疑图表在您的标签顶部绘制。当您调用 DrawToBitmap 时,图表只会考虑它所知道的视觉效果,而不是事后在顶部绘制的元素。

您需要颠倒绘图顺序。IE

  1. 将图表绘制到位图中
  2. 使用带有预渲染图表的位图,在顶部绘制标签

代码:

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 的建议:

“reference System.Drawing.Imaging, to have PixelFormatand ImageFormatavailable. 此时,图像以 .bmp 扩展名保存,而它是 .png 文件(默认)”


推荐阅读