2010-01-19 60 views
22

我有一些麻煩,從一個Web請求獲得PNG和GIF字節創建從一個MemoryStream創建BitmapImage WPF BitmapImage的。字節似乎要下載罰款和BitmapImage對象沒有問題,但是產生的圖像是不實際的渲染我的UI。只有當下載的圖像類型爲png或gif(適用於jpeg)時纔會出現問題。從MemoryStream的PNG,GIF

這裏是代碼演示了此問題:

var webResponse = webRequest.GetResponse(); 
var stream = webResponse.GetResponseStream(); 
if (stream.CanRead) 
{ 
    Byte[] buffer = new Byte[webResponse.ContentLength]; 
    stream.Read(buffer, 0, buffer.Length); 

    var byteStream = new System.IO.MemoryStream(buffer); 

    BitmapImage bi = new BitmapImage(); 
    bi.BeginInit(); 
    bi.DecodePixelWidth = 30; 
    bi.StreamSource = byteStream; 
    bi.EndInit(); 

    byteStream.Close(); 
    stream.Close(); 

    return bi; 
} 

要測試web請求被正確地獲得我試圖節省了字節磁盤上的文件下面的字節,然後使用加載圖像UriSource,而不是StreamSource,它適用於所有的圖像類型:

var webResponse = webRequest.GetResponse(); 
var stream = webResponse.GetResponseStream(); 
if (stream.CanRead) 
{ 
    Byte[] buffer = new Byte[webResponse.ContentLength]; 
    stream.Read(buffer, 0, buffer.Length); 

    string fName = "c:\\" + ((Uri)value).Segments.Last(); 
    System.IO.File.WriteAllBytes(fName, buffer); 

    BitmapImage bi = new BitmapImage(); 
    bi.BeginInit(); 
    bi.DecodePixelWidth = 30; 
    bi.UriSource = new Uri(fName); 
    bi.EndInit(); 

    stream.Close(); 

    return bi; 
} 

任何人有任何光照耀?

回答

43

.BeginInit()後直接添加bi.CacheOption = BitmapCacheOption.OnLoad

BitmapImage bi = new BitmapImage(); 
bi.BeginInit(); 
bi.CacheOption = BitmapCacheOption.OnLoad; 
... 

沒有這一點, BitmapImage默認使用延遲初始化,然後流將被關閉。在第一個例子中嘗試從可能 垃圾收集 閉合或者甚至設置的MemoryStream讀取的圖像。第二個示例使用文件,該文件仍然可用。 另外,不要寫

var byteStream = new System.IO.MemoryStream(buffer); 

更好

using (MemoryStream byteStream = new MemoryStream(buffer)) 
{ 
    ... 
} 
+6

的'BitmapCacheOption.OnLoad'技巧是很重要的。我只想補充說它應該在'BeginInit()'和'EndInit()'之間。 – 2012-01-06 09:48:44

+0

@PieterMüller:非常有幫助的線索;另外,當調用'EndInit()'作爲另一個可能會偶然發現的約束時,流仍然*必須*打開。 – 2012-09-02 19:24:57

10

我使用這個代碼:

public static BitmapImage GetBitmapImage(byte[] imageBytes) 
{ 
    var bitmapImage = new BitmapImage(); 
    bitmapImage.BeginInit(); 
    bitmapImage.StreamSource = new MemoryStream(imageBytes); 
    bitmapImage.EndInit(); 
    return bitmapImage; 
} 

可能是你應該刪除這一行:

bi.DecodePixelWidth = 30; 
+1

但對於關閉您通過創建內存流: 新的MemoryStream(imageBytes) 我想改變CacheOption比較好,應該這樣當河流關閉? – 2012-11-27 14:02:15