/Diplom/DynamicDataDisplay/Main/src/DynamicDataDisplay/Common/Auxiliary/ScreenshotHelper.cs

# · C# · 205 lines · 166 code · 28 blank · 11 comment · 22 complexity · e4d4a1b9fe7f6d9d8d9ec86f7dc7eb8c MD5 · raw file

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