Windows 8.1 Store App内截屏
在开发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: