2010-03-11 85 views
5

我想一個圖像綁定到某種控制的刪除它以後。刪除一個已經使用一個WPF圖像控件

path = @"c:\somePath\somePic.jpg" 
FileInfo fi = new FileInfo(path); 
Uri uri = new Uri(fi.FullName, UriKind.Absolute); 
var img = new System.Windows.Controls.Image(); 
img.Source = new BitmapImage(uri); 

下面這段代碼後,我想刪除的文件:

fi.Delete(); 

但我不能這樣做,因爲像現在正在使用。 代碼片段1和2之間我可以做些什麼來釋放它?

回答

3

複製到的MemoryStream它應該是這樣的

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

其中的字節流的文件的副本的MemoryStream

給予ImageSource的 前的圖像也this可以

+2

Tx,它的工作原理。對於後來的讀者:我已經將它複製到像這樣的內存流:MemoryStream byteStream = new MemoryStream(File.ReadAllBytes(path)); – Peter 2010-03-11 09:04:19

+1

是的,它的工作原理**,但效率低下**因爲:1.圖像數據的兩個副本永遠保留,2.緩存被繞過,因此圖像即使已經在RAM中也被加載。鏈接的文章解釋了#1的解決方法,但它需要很多額外的代碼,仍然不能解決#2。更好的解決方案是將'BitmapCacheOption.OnLoad'與'BeginInit/EndInit'結合。 – 2010-03-11 10:36:26

+0

難道你不能在EndInit之後關閉內存流嗎?爲什麼你需要保持兩個? 。 – Jordan 2015-08-10 14:18:55

11

你可以使用有用一個MemoryStream,但實際上浪費內存,因爲位圖數據的兩個單獨的副本保存在RAM中:當你加載MemoryStream時,你做一個副本,該位圖被解碼另一個副本。以這種方式使用MemoryStream的另一個問題是您繞過緩存。

做到這一點,最好的辦法是使用BitmapCacheOptions.OnLoad從文件直接讀取:

path = @"c:\somePath\somePic.jpg" 

var source = new BitmapImage(); 
source.BeginInit(); 
source.UriSource = new Uri(path, UriKind.RelativeOrAbsolute); 
source.CacheOption = BitmapCacheOption.OnLoad; 
source.EndInit(); // Required for full initialization to complete at this time 

var img = new System.Windows.Controls.Image { Source = source }; 

該解決方案是有效的,很簡單。

注意:如果你其實要繞過緩存,例如因爲圖像可以在磁盤上不斷變化的,你還應該設置CreateOption = BitmapCreateOption.IgnoreImageCache。但即使在這種情況下,該解決方案的性能也超過了MemoryStream解決方案,因爲它不會將圖像數據的兩個副本保留在RAM中。

+0

聽起來很不錯,但我得到一個:*無法設置初始化狀態不止一次* AT * source.BeginInit(); * – Peter 2010-03-11 10:51:56

+0

對不起:我沒有測試使用該特定構造函數重載的代碼。它似乎在內部調用'BeginInit()'和'EndInit()'。我更改了代碼以使用常規構造函數,它應該解決這個問題。 – 2010-03-11 14:53:34

+1

更多的問題:1。我看不出來源爲BitmapImage的類2的財產,如果我通過UriSource取代它,我仍然得到它未初始化...... 它的工作原理但如果我這樣使用它:\t \t var source = new BitmapImage(); \t \t \t \t source.BeginInit(); \t \t \t \t source.UriSource = new Uri(path, UriKind.Absolute); \t \t \t \t source.CacheOption = BitmapCacheOption.OnLoad; \t \t \t \t source.EndInit(); +1然而對於正確的想法,thx。 – Peter 2010-03-12 09:21:27