123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- using ReactNative.Bridge;
- using ReactNative.UIManager;
- using System;
- using System.IO;
- using System.Windows;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
-
- namespace RNViewShot
- {
- public class ViewShot : IUIBlock
- {
- public const string ErrorUnableToSnapshot = "E_UNABLE_TO_SNAPSHOT";
- private int tag;
- private string extension;
- private double quality;
- private int? width;
- private int? height;
- private string path;
- private string result;
- private IPromise promise;
-
- public ViewShot(
- int tag,
- string extension,
- double quality,
- int? width,
- int? height,
- string path,
- string result,
- IPromise promise)
- {
- this.tag = tag;
- this.extension = extension;
- this.quality = quality;
- this.width = width;
- this.height = height;
- this.path = path;
- this.result = result;
- this.promise = promise;
- }
-
- public void Execute(NativeViewHierarchyManager nvhm)
- {
- var view = nvhm.ResolveView(tag) as FrameworkElement;
- if (view == null)
- {
- promise.Reject(ErrorUnableToSnapshot, "No view found with reactTag: " + tag);
- return;
- }
-
- try
- {
- BitmapEncoder image = CaptureView(view);
-
- if ("file" == result)
- {
- string filePath = GetFilePath();
- Stream stream = File.Create(filePath);
- image.Save(stream);
- promise.Resolve(filePath);
- stream.Close();
- }
- else if ("base64" == result)
- {
- MemoryStream stream = new MemoryStream();
- image.Save(stream);
- byte[] imageBytes = stream.ToArray();
- string data = Convert.ToBase64String(imageBytes);
- promise.Resolve(data);
- stream.Close();
- }
- else if ("data-uri" == result)
- {
- MemoryStream stream = new MemoryStream();
- image.Save(stream);
- byte[] imageBytes = stream.ToArray();
- string data = Convert.ToBase64String(imageBytes);
- data = "data:image/" + extension + ";base64," + data;
- promise.Resolve(data);
- stream.Close();
- }
- else
- {
- promise.Reject(ErrorUnableToSnapshot, "Unsupported result: " + result + ". Try one of: file | base64 | data-uri");
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.ToString());
- promise.Reject(ErrorUnableToSnapshot, "Failed to capture view snapshot");
- }
- }
-
- private BitmapEncoder CaptureView(FrameworkElement view)
- {
- int w = (int)view.ActualWidth;
- int h = (int)view.ActualHeight;
-
- if (w <= 0 || h <= 0)
- {
- throw new InvalidOperationException("Impossible to snapshot the view: view is invalid");
- }
-
- RenderTargetBitmap targetBitmap = new RenderTargetBitmap(w, h, 96, 96, PixelFormats.Default);
- targetBitmap.Render(view);
-
- BitmapSource bitmap;
- if (width != null && height != null && (width != w || height != h))
- {
- double scaleX = (double)width / targetBitmap.PixelWidth;
- double scaleY = (double)height / targetBitmap.PixelHeight;
- bitmap = new TransformedBitmap(targetBitmap, new ScaleTransform(scaleX, scaleY));
- }
- else
- {
- bitmap = targetBitmap;
- }
-
- if (bitmap == null)
- {
- throw new InvalidOperationException("Impossible to snapshot the view");
- }
-
- if (extension == "png")
- {
- PngBitmapEncoder image = new PngBitmapEncoder();
- image.Frames.Add(BitmapFrame.Create(bitmap));
- return image;
- }
- else
- {
- JpegBitmapEncoder image = new JpegBitmapEncoder();
- image.QualityLevel = (int)(100.0 * quality);
- image.Frames.Add(BitmapFrame.Create(bitmap));
- return image;
- }
- }
-
- private string GetFilePath()
- {
- if (string.IsNullOrEmpty(path))
- {
- string tmpFilePath = Path.GetTempPath();
- string fileName = Guid.NewGuid().ToString();
- fileName = Path.ChangeExtension(fileName, extension);
- return Path.Combine(tmpFilePath, fileName);
- }
- else
- {
- return path;
- }
- }
- }
- }
|