【问题标题】:Creating Bitmap Image from xaml control using WritableBitmapEx使用 WritableBitmapEx 从 xaml 控件创建位图图像
【发布时间】:2013-12-10 18:23:24
【问题描述】:

如何使用 WritableBitmapEx 从 xaml 控件创建位图图像。在我的 winRT 应用程序中,我需要创建我的窗口的快照以实现 Pin to Tile(固定辅助磁贴)。我发现 winRT 中缺少 WritableBitmap.render()。如何使用 WritableBitmapEx 实现此功能。

【问题讨论】:

    标签: windows-8 windows-runtime


    【解决方案1】:

    不知何故,他们错过了实现 WriteableBitmap.Render(),虽然据我所知,它可能会出现在 SDK 的更高版本中,但现在您的选择是使用 WriteableBitmap 并使用以下内容逐像素填充它您的控制,也许在WriteableBitmapEx 的帮助下,或者使用 DirectX,也许在 SharpDX 的帮助下,它是 DirectX 的包装器,您可以在 C# 应用程序中使用。如果你想渲染任何文本,你确实需要使用 DirectX/Direct2D/DirectWrite。如果您的 UI 很简单,那么使用 DirectX 并不太难。有一个样本似乎是一个很好的起点here

    编辑*

    还有一个 WriteableBitmap.Render() extension method 我开始在 WinRT XAML Toolkit 中实现,它对渲染可视化树有一些有限但可能有用的支持。如有必要,我计划扩展它以支持更多 UI 元素。它目前支持具有纯色或渐变背景的典型文本块和形状。

    编辑 2*

    Windows 8.1 添加了RenderTargetBitmap.RenderAsync() API,这非常有用,尽管它有一些限制,例如它要求渲染的 UI 是可视化树的一部分(尽管它可以在隐藏面板中),错过了视频播放、DirectX 内容,我也相信 WebView 内容。

    【讨论】:

    • 太棒了。 RenderTargetBitmap.RenderAsync() 是大多数场景的最佳解决方案。
    【解决方案2】:

    WritableBitmapEx 自提出此问题以来已更新,现在支持 WinRT - 所以它应该可以正常工作。

    有大量的演示来展示这一点并回答了一些 SO 问题:https://gist.github.com/2834070

    【讨论】:

    • WritableBitmapEx.Render 在 Windows Phone 8.1 RT 上不可用,但在 8.1 Silverlight 中可用。
    • @user925327 与以前的版本相比,很可能缺少一些方法,但现在很多方法都在工作。
    【解决方案3】:

    我一直在使用 Windows.Storage.Streams 中的 RandomAccessStreamReference 类来创建位图。一个例子(这实际上是分享的代码):

                var reference = RandomAccessStreamReference.CreateFromUri(new Uri(item.ImagePath.AbsoluteUri));
                request.Data.SetBitmap(reference);
    

    另外请记住,对于固定辅助磁贴,您可以为磁贴上的徽标传入一个 URI,而无需创建实际的位图,只要徽标是您的应用程序包的一部分,如下所示:

            var uri = new Uri(item.TileImagePath.AbsoluteUri);
    
            var tile = new SecondaryTile(
                    item.UniqueId,              // Tile ID
                    item.ShortTitle,            // Tile short name
                    item.Title,                 // Tile display name
                    item.UniqueId,              // Activation argument
                    TileOptions.ShowNameOnLogo, // Tile options
                    uri                         // Tile logo URI
                );
    
            await tile.RequestCreateAsync();
    

    最后,如果您要在辅助磁贴上使用的图像是在线的,而不是应用程序包的一部分,则您必须先将其复制到本地,然后才能使用它。这是一些执行此操作的代码:

            // This is the URI that you will then pass as the last parameter into 
            // the Secondary Tile constructor, like the code above:
            var logoUri = await GetLocalImageAsync(restaurant.ImagePath, restaurant.Key);
    
            // and here's the method that does the meat of the work:
    
        /// <summary>
        /// Copies an image from the internet (http protocol) locally to the AppData LocalFolder.
        /// This is used by some methods (like the SecondaryTile constructor) that do not support 
        /// referencing images over http but can reference them using the ms-appdata protocol.  
        /// </summary>
        /// <param name="internetUri">The path (URI) to the image on the internet</param>
        /// <param name="uniqueName">A unique name for the local file</param>
        /// <returns>Path to the image that has been copied locally</returns>
        private async Task<Uri> GetLocalImageAsync(string internetUri, string uniqueName)
        {
            if (string.IsNullOrEmpty(internetUri))
            {
                return null;
            }
    
            using (var response = await HttpWebRequest.CreateHttp(internetUri).GetResponseAsync())
            {
                using (var stream = response.GetResponseStream())
                {
                    var desiredName = string.Format("{0}.jpg", uniqueName);
                    var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(desiredName, CreationCollisionOption.ReplaceExisting);
    
                    using (var filestream = await file.OpenStreamForWriteAsync())
                    {
                        await stream.CopyToAsync(filestream);
                        return new Uri(string.Format("ms-appdata:///local/{0}.jpg", uniqueName), UriKind.Absolute);
                    }
                }
            }
        }
    

    【讨论】:

    • 这不是我期望得到的答案。在这里,您演示了创建 PinToTile 的方法。我被问到的是不同的东西。我没有可以用手固定的图像;我的要求是,我有一个带有一些数据的控件(比如网格或画布),我需要从该控件创建一个图像,然后我需要将该图像固定到开始屏幕。希望你能理解我的问题。我可以在 wp7 和 wpf 中使用 WritableBitmap.Render () 方法从控件创建图像。但在 WINRT 中没有。我需要解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多