2009-01-09 39 views
3

我正在將Silverlight XAML發送到Web服務,該Web服務在STA線程中呈現XAML並生成PNG圖像。除了<image>條目「正常顯示」以在WPF中設置其Source屬性但PNG未顯示引用圖像時正確加載的所有XAML呈現正確外 - 我做錯了什麼?如何在後臺WPF過程中呈現<image>?

我使用的代碼的核心如下。 value對象是Silverlight的DTO,其中包含字符串中的XAML,其結尾爲sXAML本地屬性,圖像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源分配是成功的以某種方式。

+0

仍然無法讓WPF呈現背景圖片 - 不用擔心。我將背景圖像加載到位圖中,並使用渲染的XAML位圖圖像對其進行了修改,併成功生成了所需的圖像。 – user22096 2009-01-10 17:31:52

回答

2

事我會嘗試:

1)在您的WPF應用程序,如果你是渲染「您的動態加載Canvas在一個窗口中顯示,它所有的工作(包括圖片)?

2)您是否嘗試過將Loaded處理程序附加到img對象上以查看何時圖像實際加載?

3)假設#1的作品 - 圖像位於哪裏(它們在互聯網/本地網絡服務器上)?如果你把一個斷點在代碼上

bmp.Render(canvas); 

,等待踩着前一段時間 - 並像然後出現在渲染輸出?

我懷疑圖像正在異步「下載」,並且您在Image對象解決其源問題之前渲染Canvas太早。

[更新29-JAN-09] 可能的解決方案

我複製你的代碼準確地記錄了,並給它一個嘗試。當我使用「本地」圖像位置(例如「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格式顯示)。也許這會在你的情況下工作?

+0

如果您沒有將WebRequest.Create(url)返回到HttpWebRequest,它將用於本地地址(「file:// c:/foo.png」)或顯然是新Uri(「@」C:\ temp \ foo.png「)。另請注意:webrequest。CachePolicy行是必需的,至少在我需要此修復的上下文中。 – sphereinabox 2010-01-11 03:07:51