Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ImageExportDialog.cs @ 7227

Last change on this file since 7227 was 7216, checked in by abeham, 13 years ago

#1603

  • Made display name change transparent
  • Changed ok button

#1611

  • added warning and added label to show image size
  • fixed controls resizing
File size: 14.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.ComponentModel;
24using System.Drawing;
25using System.Drawing.Imaging;
26using System.IO;
27using System.Windows.Forms;
28using System.Windows.Forms.DataVisualization.Charting;
29
30namespace HeuristicLab.Visualization.ChartControlsExtensions {
31  public sealed partial class ImageExportDialog : Form {
32    private const float CMPERINCH = 2.54f;
33    private static readonly string DPI = "dpi", DPCM = "dpcm", INCH = "inch", CM = "cm";
34    private Chart originalChart, workingChart;
35    private bool SuppressEvents { get; set; }
36
37    /// <summary>
38    /// Initializes a new ImageExportDialog.
39    /// </summary>
40    /// <remarks>
41    /// Throws an ArgumentNullException if <paramref name="chart"/> is null.
42    /// </remarks>
43    /// <param name="chart">The chart for which the export should be generated.</param>
44    public ImageExportDialog(Chart chart) {
45      if (chart == null) throw new ArgumentNullException("chart");
46      this.originalChart = chart;
47      InitializeComponent();
48      #region Custom Initialization
49      SuppressEvents = true;
50      try {
51        resolutionUnitComboBox.Items.Add(DPI);
52        resolutionUnitComboBox.Items.Add(DPCM);
53        lengthUnitComboBox.Items.Add(INCH);
54        lengthUnitComboBox.Items.Add(CM);
55        resolutionUnitComboBox.SelectedIndex = 0;
56        if (System.Globalization.RegionInfo.CurrentRegion.IsMetric)
57          lengthUnitComboBox.SelectedIndex = 1;
58        else lengthUnitComboBox.SelectedIndex = 0;
59
60        titleFontSizeComboBox.Text = "12";
61        axisFontSizeComboBox.Text = "8";
62        scalesFontSizeComboBox.Text = "6";
63        legendFontSizeComboBox.Text = "6";
64        resolutionComboBox.Text = "300";
65        SuppressEvents = false;
66        splitContainer.Panel2Collapsed = true;
67        Width = 305;
68        Height = 550;
69      } finally { SuppressEvents = false; }
70      #endregion
71    }
72
73    private void UpdateFields() {
74      ChartArea area = GetCurrentChartArea();
75
76      try {
77        SuppressEvents = true;
78
79        if (workingChart.Titles.Count == 0) titleFontSizeComboBox.Text = "12";
80        else {
81          titleTextBox.Text = workingChart.Titles[0].Text;
82          titleFontSizeComboBox.Text = workingChart.Titles[0].Font.SizeInPoints.ToString();
83        }
84
85        primaryXTextBox.Text = area.AxisX.Title;
86        primaryYTextBox.Text = area.AxisY.Title;
87        secondaryXTextBox.Text = area.AxisX2.Title;
88        secondaryYTextBox.Text = area.AxisY2.Title;
89
90        axisFontSizeComboBox.Text = area.AxisX.TitleFont.SizeInPoints.ToString();
91        scalesFontSizeComboBox.Text = area.AxisX.LabelStyle.Font.SizeInPoints.ToString();
92        if (workingChart.Legends.Count == 0) legendFontSizeComboBox.Text = "8";
93        else legendFontSizeComboBox.Text = workingChart.Legends[0].Font.SizeInPoints.ToString();
94      } finally {
95        SuppressEvents = false;
96      }
97    }
98
99    private ChartArea GetCurrentChartArea() {
100      return workingChart.ChartAreas[chartAreaComboBox.Text];
101    }
102
103    private void UpdatePreview() {
104      float dpi;
105      float width;
106      float height;
107      GetImageParameters(out dpi, out width, out height);
108
109      if (previewPictureBox.Image != null) {
110        previewPictureBox.Image.Dispose();
111        previewPictureBox.Image = null;
112      }
113
114      int previewWidth, previewHeight;
115      if (width / height >= 1.0) {
116        previewWidth = previewPictureBox.Width;
117        previewHeight = (int)Math.Round(height / width * previewWidth);
118      } else {
119        previewHeight = previewPictureBox.Height;
120        previewWidth = (int)Math.Round(width / height * previewHeight);
121      }
122
123      float scaleFactor = (float)Math.Min(previewWidth / width, previewHeight / height);
124      if (scaleFactor >= 1) {
125        previewZoomLabel.Text = "100%";
126        previewWidth = (int)Math.Round(width);
127        previewHeight = (int)Math.Round(height);
128      } else previewZoomLabel.Text = (scaleFactor * 100).ToString("0") + "%";
129      rawImageSizeLabel.Text = GetRawImageSizeInMegabytes(width, height).ToString("0.00") + "M   " + "(" + Math.Round(width).ToString("0") + " x " + Math.Round(height).ToString("0") + ") pixels";
130
131      Bitmap image = new Bitmap(previewWidth, previewHeight);
132      image.SetResolution(dpi, dpi);
133      using (Graphics graphics = Graphics.FromImage(image)) {
134        if (scaleFactor < 1) graphics.ScaleTransform(scaleFactor, scaleFactor);
135        workingChart.Printing.PrintPaint(graphics, new Rectangle(0, 0, (int)Math.Round(width), (int)Math.Round(height)));
136      }
137      previewPictureBox.Image = image;
138    }
139
140    private void GetImageParameters(out float dpi, out float width, out float height) {
141      dpi = float.Parse(resolutionComboBox.Text);
142      if (resolutionUnitComboBox.Text == DPCM) dpi *= CMPERINCH;
143      width = (float)widthNumericUD.Value;
144      height = (float)heightNumericUD.Value;
145      if (lengthUnitComboBox.Text == CM) {
146        width /= CMPERINCH; height /= CMPERINCH;
147      }
148      width *= dpi; height *= dpi;
149    }
150
151    protected override void OnShown(EventArgs e) {
152      #region Create copy of chart
153      var prevContent = originalChart.Serializer.Content;
154      var prevFormat = originalChart.Serializer.Format;
155      originalChart.Serializer.Content = SerializationContents.Default;
156      originalChart.Serializer.Format = SerializationFormat.Binary;
157      MemoryStream ms = new MemoryStream();
158      originalChart.Serializer.Save(ms);
159
160      ms.Seek(0, SeekOrigin.Begin);
161      workingChart = new EnhancedChart();
162      workingChart.Serializer.Format = originalChart.Serializer.Format;
163      workingChart.Serializer.Load(ms);
164      ms.Close();
165
166      originalChart.Serializer.Content = prevContent;
167      originalChart.Serializer.Format = prevFormat;
168      #endregion
169
170      chartAreaComboBox.Items.Clear();
171      foreach (ChartArea area in originalChart.ChartAreas) {
172        chartAreaComboBox.Items.Add(area.Name);
173      }
174      chartAreaComboBox.SelectedIndex = 0;
175      base.OnShown(e);
176
177      if (togglePreviewCheckBox.Checked) UpdatePreview();
178    }
179
180    private void togglePreviewCheckBox_CheckedChanged(object sender, EventArgs e) {
181      splitContainer.Panel2Collapsed = !togglePreviewCheckBox.Checked;
182      togglePreviewCheckBox.Text = togglePreviewCheckBox.Checked ? "<" : ">";
183      if (splitContainer.Panel2Collapsed)
184        Width = cancelButton.Right + cancelButton.Margin.Right + Margin.Right + 10;
185      else
186        Width = splitContainer.Right + splitContainer.Margin.Right + Margin.Right;
187      if (togglePreviewCheckBox.Checked) UpdatePreview();
188    }
189
190    private void chartAreaComboBox_SelectedIndexChanged(object sender, EventArgs e) {
191      if (chartAreaComboBox.SelectedIndex >= 0)
192        UpdateFields();
193    }
194
195    private void titleTextBox_TextChanged(object sender, EventArgs e) {
196      if (!SuppressEvents) {
197        if (workingChart.Titles.Count > 0) {
198          workingChart.Titles[0].Text = titleTextBox.Text;
199        } else {
200          Title t = new Title(titleTextBox.Text);
201          t.Font = ChangeFontSizePt(t.Font, float.Parse(titleFontSizeComboBox.Text));
202          workingChart.Titles.Add(t);
203        }
204        if (togglePreviewCheckBox.Checked) UpdatePreview();
205      }
206    }
207
208    private void primaryXTextBox_TextChanged(object sender, EventArgs e) {
209      if (!SuppressEvents) {
210        ChartArea area = GetCurrentChartArea();
211        area.AxisX.Title = primaryXTextBox.Text;
212        if (togglePreviewCheckBox.Checked) UpdatePreview();
213      }
214    }
215
216    private void primaryYTextBox_TextChanged(object sender, EventArgs e) {
217      if (!SuppressEvents) {
218        ChartArea area = GetCurrentChartArea();
219        area.AxisY.Title = primaryYTextBox.Text;
220        if (togglePreviewCheckBox.Checked) UpdatePreview();
221      }
222    }
223
224    private void secondaryXTextBox_TextChanged(object sender, EventArgs e) {
225      if (!SuppressEvents) {
226        ChartArea area = GetCurrentChartArea();
227        area.AxisX2.Title = secondaryXTextBox.Text;
228        if (togglePreviewCheckBox.Checked) UpdatePreview();
229      }
230    }
231
232    private void secondaryYTextBox_TextChanged(object sender, EventArgs e) {
233      if (!SuppressEvents) {
234        ChartArea area = GetCurrentChartArea();
235        area.AxisY2.Title = secondaryYTextBox.Text;
236        if (togglePreviewCheckBox.Checked) UpdatePreview();
237      }
238    }
239
240    private void widthNumericUD_ValueChanged(object sender, EventArgs e) {
241      float dpi, width, height;
242      GetImageParameters(out dpi, out width, out height);
243      if (GetRawImageSizeInMegabytes(width, height) > 25) // bigger than A4 at 300dpi
244        MessageBox.Show("Warning: The image is getting quite big.");
245      if (togglePreviewCheckBox.Checked) UpdatePreview();
246    }
247
248    private void heightNumericUD_ValueChanged(object sender, EventArgs e) {
249      float dpi, width, height;
250      GetImageParameters(out dpi, out width, out height);
251      if (GetRawImageSizeInMegabytes(width, height) > 25) // bigger than A4 at 300dpi
252        MessageBox.Show("Warning: The image is getting quite big.");
253      if (togglePreviewCheckBox.Checked) UpdatePreview();
254    }
255
256    private void titleFontSizeComboBox_TextChanged(object sender, EventArgs e) {
257      if (!SuppressEvents) {
258        float fontSize;
259        if (float.TryParse(titleFontSizeComboBox.Text, out fontSize)) {
260          if (workingChart.Titles.Count > 0) {
261            workingChart.Titles[0].Font = ChangeFontSizePt(workingChart.Titles[0].Font, fontSize);
262            if (togglePreviewCheckBox.Checked) UpdatePreview();
263          }
264        }
265      }
266    }
267
268    private void axisFontSizeComboBox_TextChanged(object sender, EventArgs e) {
269      if (!SuppressEvents) {
270        float fontSize;
271        if (float.TryParse(axisFontSizeComboBox.Text, out fontSize)) {
272          ChartArea area = GetCurrentChartArea();
273          foreach (Axis a in area.Axes) {
274            a.TitleFont = ChangeFontSizePt(a.TitleFont, fontSize);
275          }
276        }
277        if (togglePreviewCheckBox.Checked) UpdatePreview();
278      }
279    }
280
281    private void scalesFontSizeComboBox_TextChanged(object sender, EventArgs e) {
282      if (!SuppressEvents) {
283        float fontSize;
284        if (float.TryParse(scalesFontSizeComboBox.Text, out fontSize)) {
285          ChartArea area = GetCurrentChartArea();
286          foreach (Axis a in area.Axes) {
287            a.LabelStyle.Font = ChangeFontSizePt(a.LabelStyle.Font, fontSize);
288          }
289        }
290        if (togglePreviewCheckBox.Checked) UpdatePreview();
291      }
292    }
293
294    private void legendFontSizeComboBox_TextChanged(object sender, EventArgs e) {
295      if (!SuppressEvents) {
296        float fontSize;
297        if (float.TryParse(legendFontSizeComboBox.Text, out fontSize)) {
298          foreach (Legend l in workingChart.Legends) {
299            l.Font = ChangeFontSizePt(l.Font, fontSize);
300          }
301        }
302        if (togglePreviewCheckBox.Checked) UpdatePreview();
303      }
304    }
305
306    private void numericComboBox_Validating(object sender, CancelEventArgs e) {
307      if (!(sender is ComboBox)) return;
308      float number;
309      e.Cancel = !float.TryParse((sender as ComboBox).Text, out number);
310    }
311
312    private void resolutionComboBox_TextChanged(object sender, EventArgs e) {
313      float resolution;
314      if (float.TryParse(resolutionComboBox.Text, out resolution)) {
315        if (togglePreviewCheckBox.Checked) UpdatePreview();
316      }
317    }
318
319    private void resolutionComboBox_Validating(object sender, CancelEventArgs e) {
320      float resolution;
321      e.Cancel = !float.TryParse(resolutionComboBox.Text, out resolution);
322    }
323
324    private void resolutionUnitComboBox_SelectedIndexChanged(object sender, EventArgs e) {
325      if (togglePreviewCheckBox.Checked) UpdatePreview();
326    }
327
328    private void lengthUnitComboBox_SelectedIndexChanged(object sender, EventArgs e) {
329      if (togglePreviewCheckBox.Checked) UpdatePreview();
330    }
331
332    private void okButton_Click(object sender, EventArgs e) {
333      float dpi;
334      float width;
335      float height;
336      GetImageParameters(out dpi, out width, out height);
337
338      Bitmap image = new Bitmap((int)Math.Round(width), (int)Math.Round(height));
339      image.SetResolution(dpi, dpi);
340      using (Graphics graphics = Graphics.FromImage(image)) {
341        workingChart.Printing.PrintPaint(graphics, new Rectangle(0, 0, image.Width, image.Height));
342      }
343
344      if (titleTextBox.Text.Trim() != String.Empty) saveFileDialog.FileName = titleTextBox.Text.Trim();
345      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
346        ImageFormat format = ImageFormat.Bmp;
347        string filename = saveFileDialog.FileName.ToLower();
348        if (filename.EndsWith("jpg")) {
349          format = ImageFormat.Jpeg;
350        } else if (filename.EndsWith("emf")) {
351          format = ImageFormat.Emf;
352        } else if (filename.EndsWith("gif")) {
353          format = ImageFormat.Gif;
354        } else if (filename.EndsWith("png")) {
355          format = ImageFormat.Png;
356        } else if (filename.EndsWith("tif")) {
357          format = ImageFormat.Tiff;
358        }
359        image.Save(saveFileDialog.FileName, format);
360      }
361
362      image.Dispose();
363
364      Cleanup();
365    }
366
367    private void cancelButton_Click(object sender, EventArgs e) {
368      Cleanup();
369    }
370
371    private void Cleanup() {
372      if (previewPictureBox.Image != null) previewPictureBox.Image.Dispose();
373      previewPictureBox.Image = null;
374      workingChart = null;
375    }
376
377    private static Font ChangeFontSizePt(Font font, float fontSize) {
378      if (font != null) {
379        float currentSize = font.Size;
380        if (currentSize != fontSize) {
381          font = new Font(font.Name, fontSize, font.Style, GraphicsUnit.Point, font.GdiCharSet, font.GdiVerticalFont);
382        }
383      }
384      return font;
385    }
386
387    private static float GetRawImageSizeInMegabytes(float width, float height) {
388      return ((3 * width * height) / (1024 * 1024));
389    }
390
391  }
392}
Note: See TracBrowser for help on using the repository browser.