Brak opisu

ViewShot.cs 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using ReactNative.Bridge;
  2. using ReactNative.UIManager;
  3. using System;
  4. using System.IO;
  5. using System.Windows;
  6. using System.Windows.Media;
  7. using System.Windows.Media.Imaging;
  8. namespace RNViewShot
  9. {
  10. public class ViewShot : IUIBlock
  11. {
  12. public const string ErrorUnableToSnapshot = "E_UNABLE_TO_SNAPSHOT";
  13. private int tag;
  14. private string extension;
  15. private double quality;
  16. private int? width;
  17. private int? height;
  18. private string path;
  19. private string result;
  20. private IPromise promise;
  21. public ViewShot(
  22. int tag,
  23. string extension,
  24. double quality,
  25. int? width,
  26. int? height,
  27. string path,
  28. string result,
  29. IPromise promise)
  30. {
  31. this.tag = tag;
  32. this.extension = extension;
  33. this.quality = quality;
  34. this.width = width;
  35. this.height = height;
  36. this.path = path;
  37. this.result = result;
  38. this.promise = promise;
  39. }
  40. public void Execute(NativeViewHierarchyManager nvhm)
  41. {
  42. var view = nvhm.ResolveView(tag) as FrameworkElement;
  43. if (view == null)
  44. {
  45. promise.Reject(ErrorUnableToSnapshot, "No view found with reactTag: " + tag);
  46. return;
  47. }
  48. try
  49. {
  50. BitmapEncoder image = CaptureView(view);
  51. if ("file" == result)
  52. {
  53. string filePath = GetFilePath();
  54. Stream stream = File.Create(filePath);
  55. image.Save(stream);
  56. promise.Resolve(filePath);
  57. stream.Close();
  58. }
  59. else if ("base64" == result)
  60. {
  61. MemoryStream stream = new MemoryStream();
  62. image.Save(stream);
  63. byte[] imageBytes = stream.ToArray();
  64. string data = Convert.ToBase64String(imageBytes);
  65. promise.Resolve(data);
  66. stream.Close();
  67. }
  68. else if ("data-uri" == result)
  69. {
  70. MemoryStream stream = new MemoryStream();
  71. image.Save(stream);
  72. byte[] imageBytes = stream.ToArray();
  73. string data = Convert.ToBase64String(imageBytes);
  74. data = "data:image/" + extension + ";base64," + data;
  75. promise.Resolve(data);
  76. stream.Close();
  77. }
  78. else
  79. {
  80. promise.Reject(ErrorUnableToSnapshot, "Unsupported result: " + result + ". Try one of: file | base64 | data-uri");
  81. }
  82. }
  83. catch (Exception ex)
  84. {
  85. Console.WriteLine(ex.ToString());
  86. promise.Reject(ErrorUnableToSnapshot, "Failed to capture view snapshot");
  87. }
  88. }
  89. private BitmapEncoder CaptureView(FrameworkElement view)
  90. {
  91. int w = (int)view.ActualWidth;
  92. int h = (int)view.ActualHeight;
  93. if (w <= 0 || h <= 0)
  94. {
  95. throw new InvalidOperationException("Impossible to snapshot the view: view is invalid");
  96. }
  97. RenderTargetBitmap targetBitmap = new RenderTargetBitmap(w, h, 96, 96, PixelFormats.Default);
  98. targetBitmap.Render(view);
  99. BitmapSource bitmap;
  100. if (width != null && height != null && (width != w || height != h))
  101. {
  102. double scaleX = (double)width / targetBitmap.PixelWidth;
  103. double scaleY = (double)height / targetBitmap.PixelHeight;
  104. bitmap = new TransformedBitmap(targetBitmap, new ScaleTransform(scaleX, scaleY));
  105. }
  106. else
  107. {
  108. bitmap = targetBitmap;
  109. }
  110. if (bitmap == null)
  111. {
  112. throw new InvalidOperationException("Impossible to snapshot the view");
  113. }
  114. if (extension == "png")
  115. {
  116. PngBitmapEncoder image = new PngBitmapEncoder();
  117. image.Frames.Add(BitmapFrame.Create(bitmap));
  118. return image;
  119. }
  120. else
  121. {
  122. JpegBitmapEncoder image = new JpegBitmapEncoder();
  123. image.QualityLevel = (int)(100.0 * quality);
  124. image.Frames.Add(BitmapFrame.Create(bitmap));
  125. return image;
  126. }
  127. }
  128. private string GetFilePath()
  129. {
  130. if (string.IsNullOrEmpty(path))
  131. {
  132. string tmpFilePath = Path.GetTempPath();
  133. string fileName = Guid.NewGuid().ToString();
  134. fileName = Path.ChangeExtension(fileName, extension);
  135. return Path.Combine(tmpFilePath, fileName);
  136. }
  137. else
  138. {
  139. return path;
  140. }
  141. }
  142. }
  143. }