Как сохранить C # Control плюс дополнительный текст на диск? - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть программа на C #, которая является консольным приложением , но использует объект Chart из System.Windows.Forms.DataVisualization.Charting без присоединения Chart к Form.

По сути, мне нужно сгенерировать граф пончика на элементе управления Chart, напечатать текст внутри центра пончика, затем сохранить график и текст в файл на диске.

Если я создаю TextAnnotation в событии PrePaint, затем сохраните диаграмму на диск с DrawToBitmap, наложенный текст не отображается в файле на диске, даже если я использую различные комбинации Chart.Flush и Chart.Update и т. д.Я могу сказать, что событие запускается и выполняется код TextAnnotation.

С другой стороны, если я вообще не использую события, вместо этого получите объект Graphics из Chart.CreateGraphics, затем Graphics.DrawString для печати текста, затем Graphics.Flush и Chart.DrawToBitmap, текст по-прежнему не отображается.

Я предполагаю, что это потому, что Chart.DrawToBitmap не знает о дополнительныхвещи, нарисованные с помощью Chart.CreateGraphics, хотя я предполагал, что Graphics.Flush позаботится об этом.

What будет лучшим способом сохранить график и текст?

РЕДАКТИРОВАТЬ: Добавлен код по запросу:

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);
}

1 Ответ

0 голосов
/ 18 сентября 2018

Я подозреваю, что график тянется поверх вашего ярлыка. Когда вы вызываете DrawToBitmap, диаграмма будет учитывать только те визуальные элементы, о которых она знает, а не элементы, нарисованные поверх.

Вам необходимо изменить порядок рисования. т.е.

  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);
}

РЕДАКТИРОВАТЬ : Обязательно следуйте предложению Джими ниже в комментариях к:

"ссылка System.Drawing.Imaging, чтобы иметь в наличии PixelFormat и ImageFormat. На данный момент изображение сохраняется как с расширением .bmp, а это файл .png (по умолчанию)"

...