Browse Source

Build out remaining features for WPF

Ryan Linton 7 years ago
parent
commit
734d7b722d
2 changed files with 95 additions and 38 deletions
  1. 9
    2
      windows/RNViewShot.Net46/RNViewShotModule.cs
  2. 86
    36
      windows/RNViewShot.Net46/ViewShot.cs

+ 9
- 2
windows/RNViewShot.Net46/RNViewShotModule.cs View File

41
             double quality = options["quality"] != null ? options.Value<double>("quality") : 1.0;
41
             double quality = options["quality"] != null ? options.Value<double>("quality") : 1.0;
42
             int? width = options["width"] != null ? options.Value<int?>("width") : null;
42
             int? width = options["width"] != null ? options.Value<int?>("width") : null;
43
             int? height = options["height"] != null ? options.Value<int?>("height") : null;
43
             int? height = options["height"] != null ? options.Value<int?>("height") : null;
44
-            string result = options["result"] != null ? options.Value<string>("result") : "file";            
44
+            string result = options["result"] != null ? options.Value<string>("result") : "file";
45
+            string path = options["path"] != null ? options.Value<string>("path") : null;
46
+
47
+            if (format != "png" && format != "jpg" && format != "jpeg")
48
+            {
49
+                promise.Reject(ViewShot.ErrorUnableToSnapshot, "Unsupported image format: " + format + ". Try one of: png | jpg | jpeg");
50
+                return;
51
+            }
45
 
52
 
46
             UIManagerModule uiManager = this._reactContext.GetNativeModule<UIManagerModule>();
53
             UIManagerModule uiManager = this._reactContext.GetNativeModule<UIManagerModule>();
47
-            uiManager.AddUIBlock(new ViewShot(tag, format, quality, width, height, result, promise));
54
+            uiManager.AddUIBlock(new ViewShot(tag, format, quality, width, height, path, result, promise));
48
         }
55
         }
49
     }
56
     }
50
 }
57
 }

+ 86
- 36
windows/RNViewShot.Net46/ViewShot.cs View File

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