Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/DynamicDataDisplay/Common/Auxiliary/ScreenshotHelper.cs @ 13808

Last change on this file since 13808 was 12503, checked in by aballeit, 9 years ago

#2283 added GUI and charts; fixed MCTS

File size: 6.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Windows.Media.Imaging;
6using System.Windows;
7using System.Windows.Media;
8using System.IO;
9using System.Diagnostics;
10using System.Windows.Threading;
11using System.Windows.Shapes;
12
13namespace Microsoft.Research.DynamicDataDisplay.Common.Auxiliary
14{
15  internal static class ScreenshotHelper
16  {
17    /// <summary>Gets the encoder by extension</summary>
18    /// <param name="extension">The extension</param>
19    /// <returns>BitmapEncoder object</returns>
20    internal static BitmapEncoder GetEncoderByExtension(string extension)
21    {
22      switch (extension)
23      {
24        case "bmp":
25          return new BmpBitmapEncoder();
26        case "jpg":
27          return new JpegBitmapEncoder();
28        case "gif":
29          return new GifBitmapEncoder();
30        case "png":
31          return new PngBitmapEncoder();
32        case "tiff":
33          return new TiffBitmapEncoder();
34        case "wmp":
35          return new WmpBitmapEncoder();
36        default:
37          throw new ArgumentException(Strings.Exceptions.CannotDetermineImageTypeByExtension, "extension");
38      }
39    }
40
41    /// <summary>Creates the screenshot of entire plotter element</summary>
42    /// <returns></returns>
43    internal static BitmapSource CreateScreenshot(UIElement uiElement, Int32Rect screenshotSource)
44    {
45      Window window = Window.GetWindow(uiElement);
46      if (window == null)
47      {
48        return CreateElementScreenshot(uiElement);
49      }
50      Size size = window.RenderSize;
51
52      //double dpiCoeff = 32 / SystemParameters.CursorWidth;
53      //int dpi = (int)(dpiCoeff * 96);
54      double dpiCoeff = 1;
55      int dpi = 96;
56
57      RenderTargetBitmap bmp = new RenderTargetBitmap(
58        (int)(size.Width * dpiCoeff), (int)(size.Height * dpiCoeff),
59        dpi, dpi, PixelFormats.Default);
60
61      // white background
62      Rectangle whiteRect = new Rectangle { Width = size.Width, Height = size.Height, Fill = Brushes.White };
63      whiteRect.Measure(size);
64      whiteRect.Arrange(new Rect(size));
65      bmp.Render(whiteRect);
66      // the very element
67      bmp.Render(uiElement);
68
69      CroppedBitmap croppedBmp = new CroppedBitmap(bmp, screenshotSource);
70      return croppedBmp;
71    }
72
73    private static BitmapSource CreateElementScreenshot(UIElement uiElement)
74    {
75      bool measureValid = uiElement.IsMeasureValid;
76
77      if (!measureValid)
78      {
79        double width = 300;
80        double height = 300;
81
82        FrameworkElement frElement = uiElement as FrameworkElement;
83        if (frElement != null)
84        {
85          if (!Double.IsNaN(frElement.Width))
86            width = frElement.Width;
87          if (!Double.IsNaN(frElement.Height))
88            height = frElement.Height;
89        }
90
91        Size size = new Size(width, height);
92        uiElement.Measure(size);
93        uiElement.Arrange(new Rect(size));
94      }
95
96      RenderTargetBitmap bmp = new RenderTargetBitmap(
97        (int)uiElement.RenderSize.Width, (int)uiElement.RenderSize.Height,
98        96, 96, PixelFormats.Default);
99
100      // this is waiting for dispatcher to perform measure, arrange and render passes
101      uiElement.Dispatcher.Invoke(((Action)(() => { })), DispatcherPriority.Background);
102
103      Size elementSize = uiElement.DesiredSize;
104      // white background
105      Rectangle whiteRect = new Rectangle { Width = elementSize.Width, Height = elementSize.Height, Fill = Brushes.White };
106      whiteRect.Measure(elementSize);
107      whiteRect.Arrange(new Rect(elementSize));
108      bmp.Render(whiteRect);
109
110      bmp.Render(uiElement);
111
112      return bmp;
113    }
114
115    private static Dictionary<BitmapSource, string> pendingBitmaps = new Dictionary<BitmapSource, string>();
116
117    internal static void SaveBitmapToStream(BitmapSource bitmap, Stream stream, string fileExtension)
118    {
119      if (bitmap == null)
120        throw new ArgumentNullException("bitmap");
121      if (stream == null)
122        throw new ArgumentNullException("stream");
123      if (String.IsNullOrEmpty(fileExtension))
124        throw new ArgumentException(Strings.Exceptions.ExtensionCannotBeNullOrEmpty, fileExtension);
125
126      BitmapEncoder encoder = ScreenshotHelper.GetEncoderByExtension(fileExtension);
127      encoder.Frames.Add(BitmapFrame.Create(bitmap, null, new BitmapMetadata(fileExtension.Trim('.')), null));
128      encoder.Save(stream);
129    }
130
131    internal static void SaveBitmapToFile(BitmapSource bitmap, string filePath)
132    {
133      if (String.IsNullOrEmpty(filePath))
134        throw new ArgumentException(Strings.Exceptions.FilePathCannotbeNullOrEmpty, "filePath");
135
136      if (bitmap.IsDownloading)
137      {
138        pendingBitmaps[bitmap] = filePath;
139        bitmap.DownloadCompleted += OnBitmapDownloadCompleted;
140        return;
141      }
142
143      string dirPath = System.IO.Path.GetDirectoryName(filePath);
144      if (!String.IsNullOrEmpty(dirPath) && !Directory.Exists(dirPath))
145      {
146        Directory.CreateDirectory(dirPath);
147      }
148
149      bool fileExistedBefore = File.Exists(filePath);
150      try
151      {
152        using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
153        {
154          string extension = System.IO.Path.GetExtension(filePath).TrimStart('.');
155          SaveBitmapToStream(bitmap, fs, extension);
156        }
157      }
158      catch (ArgumentException)
159      {
160        if (!fileExistedBefore && File.Exists(filePath))
161        {
162          try
163          {
164            File.Delete(filePath);
165          }
166          catch { }
167        }
168      }
169      catch (IOException exc)
170      {
171        Debug.WriteLine("Exception while saving bitmap to file: " + exc.Message);
172      }
173    }
174
175    public static void SaveStreamToFile(Stream stream, string filePath)
176    {
177      string dirPath = System.IO.Path.GetDirectoryName(filePath);
178      if (!String.IsNullOrEmpty(dirPath) && !Directory.Exists(dirPath))
179      {
180        Directory.CreateDirectory(dirPath);
181      }
182
183      using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
184      {
185        string extension = System.IO.Path.GetExtension(filePath).TrimStart('.');
186        if (stream.CanSeek)
187          stream.Seek(0, SeekOrigin.Begin);
188
189        stream.CopyTo(fs);
190      }
191
192      stream.Dispose();
193    }
194
195    private static void OnBitmapDownloadCompleted(object sender, EventArgs e)
196    {
197      BitmapSource bmp = (BitmapSource)sender;
198      bmp.DownloadCompleted -= OnBitmapDownloadCompleted;
199      string filePath = pendingBitmaps[bmp];
200      pendingBitmaps.Remove(bmp);
201
202      SaveBitmapToFile(bmp, filePath);
203    }
204  }
205}
Note: See TracBrowser for help on using the repository browser.