Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
在开发Windows Store App中,对应用程序进行截图是经常面临的一个问题。但是由于API的限制,我们没有办法对Windows Store App进行截屏。不过,Windows 8.1的出现带来了新的希望:
Rendering the XAML tree to a bitmap
接下来我将要用简单的代码来演示一下这两个新的API。
Rendering the XAML tree to a bitmap
Windows 8.1的runtime在Windows.UI.Xaml.Media.Imaging中新加入了RenderTargetBitmap,而这里有两个非常重要的方法:
RenderTargetBitmap.RenderAsync:把UIElement渲染成图片。
RenderTargetBitmap.GetPixelsAsync:把RenderTargetBitmap图片保存成BGRA8格式的流文件。
下面是在XAML render to bitmap 示例中找的一份C#代码,具体的代码可以在示例中下载:
Render XAML Tree to image source
1: RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
2: await renderTargetBitmap.RenderAsync(RenderedGrid);
3: RenderedImage.Source = renderTargetBitmap;
Render XAML Tree to file
1: // Render to an image at the current system scale and retrieve pixel contents
2: RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
3: await renderTargetBitmap.RenderAsync(RenderedGrid);
4: var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
5:
6: var savePicker = new FileSavePicker();
7: savePicker.DefaultFileExtension = ".png";
8: savePicker.FileTypeChoices.Add(".png", new List<string> { ".png" });
9: savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
10: savePicker.SuggestedFileName = "snapshot.png";
11:
12: // Prompt the user to select a file
13: var saveFile = await savePicker.PickSaveFileAsync();
14:
15: // Verify the user selected a file
16: if (saveFile == null)
17: return;
18:
19: // Encode the image to the selected file on disk
20: using (var fileStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
21: {
22: var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);
23:
24: encoder.SetPixelData(
25: BitmapPixelFormat.Bgra8,
26: BitmapAlphaMode.Ignore,
27: (uint)renderTargetBitmap.PixelWidth,
28: (uint)renderTargetBitmap.PixelHeight,
29: DisplayInformation.GetForCurrentView().LogicalDpi,
30: DisplayInformation.GetForCurrentView().LogicalDpi,
31: pixelBuffer.ToArray());
32:
33: await encoder.FlushAsync();
34: }
WebView for JavaScript
Windows 8.1在WebView控件中做了很多改动,例如新加了GoBack, GoForward, Stop,Refresh, CanGoBack和CanGoForward。之后我们也不需要再用JavaScript的方法去实现相同的结果了。新的属性的增加使得WebView变得更加的强大。之后我再详细说明这些变化。
这里我将要介绍一下CapturePreviewToStreamAsync,这个方法使得在Windows Store App中通过Javascript截屏变为可能。
下面代码是介绍如何使用CapturePreviewToStreamAsync去截屏:
1: <body>
2: <p>Content goes here</p>
3: <input type="url" id="urlField" />
4: <button id="goOrStopButton">Go</button>
5: <button id="captureToImage">capture</button>
6: <div>
7: <x-ms-webview id="webview" style="width:1000px;height:800px"></x-ms-webview>
8: </div>
9: </body>
1: var page = WinJS.UI.Pages.define("default.html", {
2: ready: function (element, options) {
3: document.getElementById("goOrStopButton").addEventListener("click", goToUrl, false);
4: document.getElementById("captureToImage").addEventListener("click", captureToImage, false);
5: var webviewControl = document.getElementById("webview");
6: webviewControl.navigate("https://go.microsoft.com/fwlink/?LinkId=294155");
7: }
8: });
9:
10: function goToUrl() {
11: var destinationUrl = document.getElementById("urlField").value;
12: try {
13: document.getElementById("webview").navigate(destinationUrl);
14: } catch (error) {
15: WinJS.log && WinJS.log("\"" + destinationUrl + "\" is not a valid absolute URL.\n", "sdksample", "error");
16: return;
17: }
18: }
19:
20: function captureToImage() {
21: var webviewControl = document.getElementById("webview");
22: Windows.Storage.ApplicationData.current.localFolder.createFileAsync("test.png", ndows.Storage.CreationCollisionOption.replaceExisting).then(function (file) {
23: file.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (stream) {
24: var captureOperation = webviewControl.capturePreviewToBlobAsync();
25: captureOperation.oncomplete = function (completeEvent) {
26: var inputStream = completeEvent.target.result.msDetachStream();
27: Windows.Storage.Streams.RandomAccessStream.copyAsync(inputStream, stream).then(function () {
28: stream.flushAsync().done(function () {
29: inputStream.close();
30: stream.close();
31: });
32: });
33: };
34: captureOperation.start();
35: });
36: });
37: }
剩下的过程就非常简单了:通过innerHTML property获取到HTML,然后再获取WebView就可以了。
English Version: