【问题标题】:Generate image from Silverlight 4 XAML on server-side without rendering UI in browser在服务器端从 Silverlight 4 XAML 生成图像,而不在浏览器中呈现 UI
【发布时间】:2011-07-12 11:09:04
【问题描述】:

我目前正在尝试实现一些报告功能,这需要我将一些 Silverlight XAML 内容转换为图像,而无需在 Silverlight 客户端上实际生成 UI。

我要解决的问题是 - 我如何将 Silverlight XAML 呈现为图像而不首先显示在 Silverlight 客户端上?我之前唯一一次这样做是使用 WriteableBitmap API 将当前显示的 UI 呈现为图像,然后根据需要转换为 PNG/JPEG。由于我可以选择呈现 XAML 服务器端,因此我希望使用 WPF 功能来呈现 XAML - 但由于它是 Silverlight XAML,这是否可行?

如果没有很好的方法来做到这一点,据我所知,另一个选择是尝试渲染隐藏在 PDF 查看器 Silverlight 客户端控件背景中的 UI,拉出可写位图并以这种方式生成它 -但显然这种方法存在开销,而且并不理想......

对此表示赞赏,这让我在过去的几天里摸不着头脑!

【问题讨论】:

    标签: wpf xaml silverlight-4.0 c#-4.0


    【解决方案1】:

    我会尝试使用 WPF 运行时来呈现 XAML 并从中生成 BMP。通常,在 Silverlight 中工作的 XAML 将在 WPF 中工作,但并非总是如此。

    WPF 应该允许您以编程方式实例化控件或加载松散的 XAML。然后你可以告诉它更新布局,最后将视觉捕捉到位图。

    编辑

    要在服务器上获取 xaml,我建议您在解决方案中创建一个新的 WPF 类库项目。然后“添加现有”项目到该项目并选择将所需的 xaml 文件添加为“链接”文件,而不是复制它们。这样,您可以在 silverlight 和 wpf 项目之间共享单个文件。

    编译该 DLL 并在将返回图像输出的服务或页面中的服务器上使用它。在该页面中,创建用户控件的实例,设置数据上下文,并输出图像。要从视觉对象中捕获图像,您可以使用 RenderTargetBitmap。

    这是一个sn-p:

    var arrangeSize = new Size(300, 300);
    var arrangeRect = new Rect(new Point(0, 0), arrangeSize);
    
    var control = new MyControl();
    control.DataContext = new MyViewModel();
    control.Measure(arrangeSize);
    control.Arrange(arrangeRect);
    control.InvalidateVisual();
    control.UpdateLayout();
    
    RenderTargetBitmap renderTarget =
        new RenderTargetBitmap(
            arrangeSize.X,
            arrangeSize.Y,
            96,
            96,
            System.Windows.Media.PixelFormats.Default
        );
    
    renderTarget.Render(control);
    
    var encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(renderTarget));
    
    using (var pageOutStream = new FileStream(targetSavePath + ".png", FileMode.Create, FileAccess.Write))
    {
        encoder.Save(pageOutStream);
        pageOutStream.Close();
    }
    

    【讨论】:

    • 谢谢,我会看看这样做,看看我能得到什么。无论如何,我在对象中有 UI 布局和属性,因此在 WPF 中创建 XAML 应该足够简单......我只是担心 SL 和 WPF XAML 之间的不兼容性
    • OK 有时间来看看这个 - 关于如何将 Silverlight XAML 发送回服务器的任何想法? XamlWriter 在 SL 中不可用。另外,看起来我必须在生成 XAML 之前在 LayoutRoot 中呈现 CLR 对象控件?
    • 添加示例并回复您的问题。我假设您没有在 silverlight 解决方案中动态生成 xaml。如果该假设是正确的,则上述方法可能有效。您只需将适当的数据发送回服务器,以便实例化控件、将数据绑定回控件并渲染图像。
    • 感谢 Nathan - 今天才看到您的回复,所以与此同时,我一直在考虑在 SL 中使用 ViewBox 并通过在代码隐藏中添加控件对象来完成这一切。您说我不生成 XAML 是正确的,我只有一个 UIElement 对象列表,其中已经包含我需要的内容数据,因此绑定不是问题。最初尝试了 WPF 方法后,我遇到了一些与 SL 和 WPF 中的 UIElement 命名空间冲突的问题。不过,将此方法保留在后袋中以供审查,谢谢!
    • 您需要 XamlWriter 的第三方实现,请参阅dropbox.com/sh/r06lsr6bwh4x5a2/AABJW_KTbnDWuqkGeqtbcTzaa 了解各种选项
    【解决方案2】:

    一个不寻常的请求......可能适合您的目的是 Chromium,特别是它的一些 .Net 包装器。您可以在内存中对其进行实例化,向其呈现 HTML 页面(包括 Silverlight),然后将其呈现为图像(该功能内置于包装器中)。现在这意味着您仍在“下载”和“渲染”页面,但您还声明在服务器端执行此操作是可以的。

    我熟悉的两个 Chromium 包装器是 AwesomiumTroymium。 Awesomium 是专业开发的,具有相当有吸引力的独立许可模式,而 Troymium 仍处于测试阶段,可能还没有那么成熟,但具有更广泛的包装(目前是免费的)。 Awesomium 包含一个下载网页然后将其渲染为图像的示例。

    请注意,您将无法使用任何 WPF 功能,Silverlight 使用单独的运行时。

    【讨论】:

    • 不寻常的请求好吧,但是一个很好的答复,如果我不能使用 WPF 呈现 XAML,这将是我的下一个停靠点。干杯,会及时更新
    【解决方案3】:

    经过多次尝试和失败后,我决定在服务器端使用 GDI 渲染 UI。

    花了太多时间试图用 Silverlight 强制执行此操作,感谢所有建议。

    【讨论】:

      猜你喜欢
      • 2018-02-28
      • 1970-01-01
      • 2014-11-14
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      相关资源
      最近更新 更多