【问题标题】:RenderTargetBitmap does not render included imagesRenderTargetBitmap 不渲染包含的图像
【发布时间】:2015-12-05 14:07:39
【问题描述】:

我想使用 RenderTargetBitmap 功能将 XAML 控件呈现为 PNG 文件。到目前为止效果很好。

但如果 XAML 包含任何图像,则这些图像不会呈现在 PNG 文件中。 这是我的 XAML:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Name="LayoutRoot"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d"
  d:DesignHeight="336"
  d:DesignWidth="336"
  Background="DarkGray">

<TextBlock Text="This is my Text"
           FontSize="35"
           HorizontalAlignment="Center" />
<Image Source="http://www.myurl.com/image.png"
       Height="200" /></Grid>

这是我的代码:

private BitmapSource RenderToBitmap(FrameworkElement target)
    {
        Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
        RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)target.ActualWidth,
          (int)target.ActualHeight,
          96, 96, PixelFormats.Pbgra32);

        DrawingVisual visual = new DrawingVisual();
        using (DrawingContext context = visual.RenderOpen())
        {
            VisualBrush brush = new VisualBrush(target);
            context.DrawRectangle(brush, null, new Rect(new Point(), bounds.Size));
        }
        renderBitmap.Render(visual);
        return renderBitmap;
    }

还尝试使用“/Assets/image.png”等引用图像和资源。每次渲染的 PNG 文件中缺少图像时。

【问题讨论】:

  • 您检查过您的图片网址吗? http://www.myurl.com/image.png 对我来说是空白的。
  • 这只是这个问题的虚拟 URL。它也不适用于正确的图像 URL。
  • 尝试在开头调用target.ApplyTemplate()
  • 您确定图像在渲染时已加载?

标签: c# wpf image xaml


【解决方案1】:

首先发生的是你渲染了你的目标,但是你的 ImageControl 异步加载 BitmapSource 并且在那一刻还没有准备好。如果您等到 ImageControl 完成加载其源代码,您将得到您所期望的。有趣的是,ImageControl 加载完成后不会通知您。

所以,简短的 answer 将是: 如果您想将现有的和已经加载的视觉呈现到图像上,只需等待嵌套的图像控件被加载。

像这样:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        img.LayoutUpdated += img_LayoutUpdated;
    }

    void img_LayoutUpdated(object sender, EventArgs e)
    {
        img.LayoutUpdated -= img_LayoutUpdated;
        var rt = RenderToBitmap(img);
        Save(rt);
    }

据我所知,没有简单的方法可以强制 ImageControl 加载其源代码。当 ImageControl 抛出“Loaded”事件时,并不意味着图像已加载。如果您将 ImageControl.Source 创建为 BitmapImage,您可以这样做:

            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.DecodePixelHeight = 100;
            bi.CacheOption = BitmapCacheOption.OnLoad;
            bi.UriSource = new Uri(@"http://www.myurl.com/image.png");
            bi.EndInit();
            bi.DownloadCompleted += bi_DownloadCompleted; //will be ready to be saved to image when event will fire
            img.Source = bi;

或者像这样自己下载图片

    WebClient wc = new WebClient();
    using (MemoryStream stream = new MemoryStream(wc.DownloadData(@"http://www.google.ru/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png")))
    {
        BitmapImage myBitmapImage = new BitmapImage();
        myBitmapImage.BeginInit();
        myBitmapImage.StreamSource = stream;
        myBitmapImage.DecodePixelWidth = 200;
        myBitmapImage.EndInit();
        img.Source = myBitmapImage;
        // ready to be saved to image
    }

但在我看来它并不适合你

如果您的目的是在内存中呈现视觉效果,那么您应该看看这个问题: Drawing a WPF UserControl with DataBinding to an Image

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-20
    • 1970-01-01
    • 2021-05-23
    • 2017-09-17
    • 2022-12-21
    • 1970-01-01
    • 2013-07-06
    • 2020-01-16
    相关资源
    最近更新 更多