如何在后台WPF进程中呈现<img/>?

时间:2009-01-09 00:37:51

标签: wpf silverlight xaml

我正在使用Silverlight XAML并将其发送到Web服务,该服务在STA线程中呈现XAML并生成PNG图像。所有XAML都正确呈现,除了<image>条目,当它们在WPF中设置Source属性但“PNG未显示引用的图像”时,“看起来”正确加载 - 我做错了什么?

我使用的代码核心如下。 value对象是Silverlight中的DTO,其中包含字符串中的XAML,最终为sXAML本地属性,而Image URI位于value.ImageURL属性中。

  var canvas = (FrameworkElement)XamlReader.Load(new XmlTextReader(new StringReader(sXAML)));

  var obj = canvas.FindName("BGImage");
  Image img = null;
  if (obj != null)
  {
    img = obj as Image;
    img.ImageFailed += img_ImageFailed;
    img.Source = new BitmapImage(new Uri(value.ImageURL, UriKind.Absolute));
  }

  canvas.Arrange(new Rect(new Size(463d, 381d)));
  canvas.UpdateLayout();

  var mem = new MemoryStream();
  var bmp = new RenderTargetBitmap(463, 381, 96d, 96d, PixelFormats.Pbgra32);
  bmp.Render(canvas);

  var encoder = new PngBitmapEncoder();
  encoder.Frames.Add(BitmapFrame.Create(bmp));
  encoder.Save(mem);

  FileStream fs = new FileStream("D:\\out.png", FileMode.Create);
  mem.WriteTo(fs);
  fs.Close();

注意:永远不会调用img_ImageFailed事件处理程序,表明img源分配在某种程度上是成功的。

1 个答案:

答案 0 :(得分:2)

我会尝试的事情:

1)在你的WPF应用程序中,如果你'渲染'你动态加载的Canvas以在一个窗口中显示,它是否全部有效(包括图像)?

2)您是否尝试将Loaded处理程序附加到img对象,以便在实际加载图像时查看

3)假设#1工作 - 图像位于何处(是否在互联网/本地网络服务器上)?如果在代码中放置断点

bmp.Render(canvas);

并在踩到之前等待一段时间 - 图像然后出现在渲染输出中吗?

我怀疑图像是异步“下载”的,并且在Canvas对象解析其来源之前,您过早地呈现Image

[更新09年1月29日] 可能的解决方案

我完全复制了你的代码并尝试了一下。当我使用“本地”图像位置(例如“c:\ images \ splash.jpg”)时,图像在输出jpeg中呈现得很好。当我使用URL(例如“http://localhost/images/splash.jpg”)时,它没有出现(正如您所描述的那样)。

所以我修改了你的代码如下(尝试强制下载图像 - 只适用于http:图像引用) -

if (obj != null)
{
    img = obj as Image;
    // new stuff
    BitmapImage bi = new BitmapImage();
    bi.BeginInit();
    bi.StreamSource = getCachedURLStream(new Uri(ImageURL));
    bi.EndInit();
    img.BeginInit();
    img.Source = bi;
    img.EndInit();
    //img.ImageFailed += img_ImageFailed;
    //img.Loaded += new RoutedEventHandler(img_Loaded);
    //img.Source = new BitmapImage(new Uri(ImageURL, UriKind.Absolute));
}
public static Stream getCachedURLStream(Uri url)
{
    HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
    WebResponse response;
    webrequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
    response = webrequest.GetResponse();
    Stream s = response.GetResponseStream();
    BufferedStream bs = new BufferedStream(s, 8192);
    return bs;
}

getCachedURLStream方法来自synchronous image loading - 它有点无关,但我只想要一大堆代码进行测试)然后它似乎工作(图像以JPEG格式显示)。也许这会在你的场景中起作用?