瀏覽代碼

Screenshots working

Ryan Linton 7 年之前
父節點
當前提交
99f293ba35

+ 8
- 0
windows/RNViewShot.Net46/RNViewShot.Net46.csproj 查看文件

@@ -70,14 +70,22 @@
70 70
       <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
71 71
       <Private>True</Private>
72 72
     </Reference>
73
+    <Reference Include="PresentationCore" />
74
+    <Reference Include="PresentationFramework" />
73 75
     <Reference Include="System" />
74 76
     <Reference Include="System.Core" />
77
+    <Reference Include="System.Drawing" />
78
+    <Reference Include="System.Windows" />
75 79
     <Reference Include="System.Xml.Linq" />
76 80
     <Reference Include="System.Data.DataSetExtensions" />
77 81
     <Reference Include="Microsoft.CSharp" />
78 82
     <Reference Include="System.Data" />
79 83
     <Reference Include="System.Net.Http" />
80 84
     <Reference Include="System.Xml" />
85
+    <Reference Include="Windows.Foundation.UniversalApiContract">
86
+      <HintPath>..\..\..\..\..\..\..\..\..\Program Files (x86)\Windows Kits\10\References\Windows.Foundation.UniversalApiContract\2.0.0.0\Windows.Foundation.UniversalApiContract.winmd</HintPath>
87
+    </Reference>
88
+    <Reference Include="WindowsBase" />
81 89
   </ItemGroup>
82 90
   <ItemGroup>
83 91
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 15
- 43
windows/RNViewShot.Net46/RNViewShotModule.cs 查看文件

@@ -1,9 +1,9 @@
1 1
 using Newtonsoft.Json.Linq;
2 2
 using ReactNative.Bridge;
3
+using ReactNative.UIManager;
3 4
 using System;
5
+using System.IO;
4 6
 using System.Collections.Generic;
5
-//using Windows.ApplicationModel.Core;
6
-//using Windows.UI.Core;
7 7
 
8 8
 namespace RNViewShot
9 9
 {
@@ -12,14 +12,15 @@ namespace RNViewShot
12 12
     /// </summary>
13 13
     class RNViewShotModule : ReactContextNativeModuleBase
14 14
     {
15
-        private ReactContext reactContext;
15
+        private const string ErrorUnableToSnapshot = "E_UNABLE_TO_SNAPSHOT";
16
+        private readonly ReactContext _reactContext;
16 17
 
17 18
         /// <summary>
18 19
         /// Instantiates the <see cref="RNViewShotModule"/>.
19 20
         /// </summary>
20
-        public RNViewShotModule(ReactContext reactContext) : base(reactContext) 
21
+        public RNViewShotModule(ReactContext reactContext) : base(reactContext)
21 22
         {
22
-            this.reactContext = reactContext;
23
+            this._reactContext = reactContext;
23 24
         }
24 25
 
25 26
         /// <summary>
@@ -34,45 +35,16 @@ namespace RNViewShot
34 35
         }
35 36
 
36 37
         [ReactMethod]
37
-        public void takeSnapshot(int tag, JObject options, IPromise promise) {
38
-            // Android Equivalent Code
39
-            //ReactApplicationContext context = getReactApplicationContext();
40
-            //String format = options.hasKey("format") ? options.getString("format") : "png";
41
-            //Bitmap.CompressFormat compressFormat =
42
-            //        format.equals("png")
43
-            //                ? Bitmap.CompressFormat.PNG
44
-            //                : format.equals("jpg") || format.equals("jpeg")
45
-            //                ? Bitmap.CompressFormat.JPEG
46
-            //                : format.equals("webm")
47
-            //                ? Bitmap.CompressFormat.WEBP
48
-            //                : null;
49
-            //if (compressFormat == null)
50
-            //{
51
-            //    promise.reject(ViewShot.ERROR_UNABLE_TO_SNAPSHOT, "Unsupported image format: " + format + ". Try one of: png | jpg | jpeg");
52
-            //    return;
53
-            //}
54
-            //double quality = options.hasKey("quality") ? options.getDouble("quality") : 1.0;
55
-            //DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
56
-            //Integer width = options.hasKey("width") ? (int)(displayMetrics.density * options.getDouble("width")) : null;
57
-            //Integer height = options.hasKey("height") ? (int)(displayMetrics.density * options.getDouble("height")) : null;
58
-            //String result = options.hasKey("result") ? options.getString("result") : "file";
59
-            //Boolean snapshotContentContainer = options.hasKey("snapshotContentContainer") ? options.getBoolean("snapshotContentContainer") : false;
60
-            //try
61
-            //{
62
-            //    String name = options.hasKey("filename") ? options.getString("filename") : null;
63
-            //    File tmpFile = "file".equals(result) ? createTempFile(getReactApplicationContext(), format, name) : null;
64
-            //    UIManagerModule uiManager = this.reactContext.getNativeModule(UIManagerModule.class);
65
-            //    uiManager.addUIBlock(new ViewShot(tag, format, compressFormat, quality, width, height, tmpFile, result, snapshotContentContainer, promise));
66
-            //}
67
-            //catch (Exception e) {
68
-            //    promise.reject(ViewShot.ERROR_UNABLE_TO_SNAPSHOT, "Failed to snapshot view tag "+tag);
69
-            //}
38
+        public void takeSnapshot(int tag, JObject options, IPromise promise)
39
+        {
40
+            string format = options["format"] != null ? options.Value<string>("format") : "png";
41
+            double quality = options["quality"] != null ? options.Value<double>("quality") : 1.0;
42
+            int? width = options["width"] != null ? options.Value<int?>("width") : null;
43
+            int? height = options["height"] != null ? options.Value<int?>("height") : null;
44
+            string result = options["result"] != null ? options.Value<string>("result") : "file";            
70 45
 
71
-            //Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
72
-            //Graphics graphics = Graphics.FromImage(bitmap as Image);
73
-            //graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
74
-            //bitmap.Save("c:\\screenshot.jpeg", ImageFormat.Jpeg);
75
-            promise.Resolve("This is working!");
46
+            UIManagerModule uiManager = this._reactContext.GetNativeModule<UIManagerModule>();
47
+            uiManager.AddUIBlock(new ViewShot(tag, format, quality, width, height, result, promise));
76 48
         }
77 49
     }
78 50
 }

+ 99
- 6
windows/RNViewShot.Net46/ViewShot.cs 查看文件

@@ -1,12 +1,105 @@
1
-using System;
2
-using System.Collections.Generic;
3
-using System.Linq;
4
-using System.Text;
5
-using System.Threading.Tasks;
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;
6 8
 
7 9
 namespace RNViewShot
8 10
 {
9
-    class ViewShot
11
+    public class ViewShot : IUIBlock
10 12
     {
13
+        private const string ErrorUnableToSnapshot = "E_UNABLE_TO_SNAPSHOT";
14
+        private int tag;
15
+        private string extension;
16
+        private double quality;
17
+        private int? width;
18
+        private int? height;
19
+        private string result;
20
+        private IPromise promise;
21
+
22
+        public ViewShot(
23
+            int tag,
24
+            string extension,
25
+            double quality,
26
+            int? width,
27
+            int? height,
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.result = result;
37
+            this.promise = promise;
38
+        }
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
+            int width = (int)view.ActualWidth;
49
+            int height = (int)view.ActualHeight;
50
+
51
+            RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default);
52
+            renderTargetBitmap.Render(view);
53
+
54
+            BitmapEncoder image;
55
+            if (extension == "png")
56
+            {
57
+                image = new PngBitmapEncoder();
58
+            }
59
+            else if (extension == "jpg" || extension == "jpeg")
60
+            {
61
+                image = new JpegBitmapEncoder();
62
+            }
63
+            else
64
+            {
65
+                promise.Reject(ErrorUnableToSnapshot, "Unsupported image format: " + extension + ". Try one of: png | jpg | jpeg");
66
+                return;
67
+            }
68
+
69
+            // TODO: Allow setting quality
70
+            image.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
71
+
72
+            if ("file" == result)
73
+            {
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
+                }
80
+            }
81
+            else if ("base64" == result)
82
+            {
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
+
89
+            }
90
+            else if ("data-uri" == result)
91
+            {
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);
98
+            }
99
+            else
100
+            {
101
+                promise.Reject(ErrorUnableToSnapshot, "Unsupported result: " + result + ". Try one of: file | base64 | data-uri");
102
+            }
103
+        }
11 104
     }
12 105
 }

+ 26
- 20
windows/RNViewShot/RNViewShotModule.cs 查看文件

@@ -1,6 +1,8 @@
1 1
 using Newtonsoft.Json.Linq;
2 2
 using ReactNative.Bridge;
3
+using ReactNative.UIManager;
3 4
 using System;
5
+using System.IO;
4 6
 using System.Collections.Generic;
5 7
 using Windows.ApplicationModel.Core;
6 8
 using Windows.UI.Core;
@@ -12,14 +14,15 @@ namespace RNViewShot
12 14
     /// </summary>
13 15
     class RNViewShotModule : ReactContextNativeModuleBase
14 16
     {
15
-        private ReactContext reactContext;
17
+        private const string ErrorUnableToSnapshot = "E_UNABLE_TO_SNAPSHOT";
18
+        private readonly ReactContext _reactContext;
16 19
 
17 20
         /// <summary>
18 21
         /// Instantiates the <see cref="RNViewShotModule"/>.
19 22
         /// </summary>
20 23
         public RNViewShotModule(ReactContext reactContext) : base(reactContext) 
21 24
         {
22
-            this.reactContext = reactContext;
25
+            this._reactContext = reactContext;
23 26
         }
24 27
 
25 28
         /// <summary>
@@ -34,10 +37,9 @@ namespace RNViewShot
34 37
         }
35 38
 
36 39
         [ReactMethod]
37
-        public void takeSnapshot(int tag, JObject options, IPromise promise) {
38
-            // Android Equivalent Code
39
-            //ReactApplicationContext context = getReactApplicationContext();
40
-            //String format = options.hasKey("format") ? options.getString("format") : "png";
40
+        public void takeSnapshot(int tag, JObject options, IPromise promise)
41
+        {
42
+            string format = options["format"] != null ? options.Value<string>("format") : "png";
41 43
             //Bitmap.CompressFormat compressFormat =
42 44
             //        format.equals("png")
43 45
             //                ? Bitmap.CompressFormat.PNG
@@ -48,31 +50,35 @@ namespace RNViewShot
48 50
             //                : null;
49 51
             //if (compressFormat == null)
50 52
             //{
51
-            //    promise.reject(ViewShot.ERROR_UNABLE_TO_SNAPSHOT, "Unsupported image format: " + format + ". Try one of: png | jpg | jpeg");
53
+            //    promise.reject(ErrorUnableToSnapshot, "Unsupported image format: " + format + ". Try one of: png | jpg | jpeg");
52 54
             //    return;
53 55
             //}
54
-            //double quality = options.hasKey("quality") ? options.getDouble("quality") : 1.0;
55
-            //DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
56
-            //Integer width = options.hasKey("width") ? (int)(displayMetrics.density * options.getDouble("width")) : null;
57
-            //Integer height = options.hasKey("height") ? (int)(displayMetrics.density * options.getDouble("height")) : null;
58
-            //String result = options.hasKey("result") ? options.getString("result") : "file";
59
-            //Boolean snapshotContentContainer = options.hasKey("snapshotContentContainer") ? options.getBoolean("snapshotContentContainer") : false;
56
+            double quality = options["quality"] != null ? options.Value<double>("quality") : 1.0;
57
+            int? width = options["width"] != null ? options.Value<int?>("width") : null;
58
+            int? height = options["height"] != null ? options.Value<int?>("height") : null;
59
+            string result = options["result"] != null ? options.Value<string>("result") : "file";
60
+            bool snapshotContentContainer = options["snapshotContentContainer"] != null ? options.Value<bool>("snapshotContentContainer") : false;
61
+
62
+            UIManagerModule uiManager = this._reactContext.GetNativeModule<UIManagerModule>();
63
+            uiManager.AddUIBlock(new ViewShot(tag));
64
+
60 65
             //try
61 66
             //{
62
-            //    String name = options.hasKey("filename") ? options.getString("filename") : null;
63
-            //    File tmpFile = "file".equals(result) ? createTempFile(getReactApplicationContext(), format, name) : null;
64
-            //    UIManagerModule uiManager = this.reactContext.getNativeModule(UIManagerModule.class);
65
-            //    uiManager.addUIBlock(new ViewShot(tag, format, compressFormat, quality, width, height, tmpFile, result, snapshotContentContainer, promise));
67
+            //    string name = options["filename"] != null ? options.Value<string>("filename") : null;
68
+            //    //File tmpFile = "file" == result ? createTempFile(this._reactContext, format, name) : null;
69
+            //    UIManagerModule uiManager = this._reactContext.GetNativeModule<UIManagerModule>();
70
+            //    //uiManager.addUIBlock(new ViewShot(tag, format, compressFormat, quality, width, height, tmpFile, result, snapshotContentContainer, promise));
66 71
             //}
67
-            //catch (Exception e) {
68
-            //    promise.reject(ViewShot.ERROR_UNABLE_TO_SNAPSHOT, "Failed to snapshot view tag "+tag);
72
+            //catch (Exception e)
73
+            //{
74
+            //    promise.reject(ErrorUnableToSnapshot, "Failed to snapshot view tag " + tag);
69 75
             //}
70 76
 
71 77
             //Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
72 78
             //Graphics graphics = Graphics.FromImage(bitmap as Image);
73 79
             //graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
74 80
             //bitmap.Save("c:\\screenshot.jpeg", ImageFormat.Jpeg);
75
-            promise.Resolve("This is working!");
81
+            promise.Resolve("Format: " + format + " Quality: " + quality);
76 82
         }
77 83
     }
78 84
 }

+ 15
- 1
windows/RNViewShot/ViewShot.cs 查看文件

@@ -3,10 +3,24 @@ using System.Collections.Generic;
3 3
 using System.Linq;
4 4
 using System.Text;
5 5
 using System.Threading.Tasks;
6
+using ReactNative.UIManager;
6 7
 
7 8
 namespace RNViewShot
8 9
 {
9
-    class ViewShot
10
+    public class ViewShot : IUIBlock
10 11
     {
12
+        private int tag;
13
+
14
+        public ViewShot(int tag)
15
+        {
16
+            this.tag = tag;
17
+        }
18
+
19
+        public void Execute(NativeViewHierarchyManager nvhm)
20
+        {
21
+            var view = nvhm.ResolveView(this.tag);
22
+
23
+            string depObj = view.ToString();
24
+        }
11 25
     }
12 26
 }