Eliminazione di un'immagine che è stata utilizzata da un controllo WPF
-
19-09-2019 - |
Domanda
Vorrei associare un'immagine ad un qualche tipo di controllo di un eliminarlo in seguito.
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);
Ora, dopo questo codice vorrei cancellare il file:
fi.Delete();
Ma non posso farlo in quanto l'immagine è in uso oggi. Tra il frammento di codice 1 en 2 cosa posso fare per liberarlo?
Soluzione
copiare l'immagine MemoryStream prima di dare a Imagesource dovrebbe assomigliare a questo
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.DecodePixelWidth = 30;
bi.StreamSource = byteStream;
bi.EndInit();
dove Bytestream è copia del file in MemoryStream
questo può essere utile
Altri suggerimenti
È possibile utilizzare un MemoryStream
ma che in realtà spreca memoria perché due copie separate dei dati bitmap sono tenuti in RAM: Quando si carica il MemoryStream
si effettua una copia, e quando la bitmap viene decodificato è fatta un'altra copia. Un altro problema con l'utilizzo MemoryStream
in questo modo è che si ignora la cache.
Il modo migliore per farlo è quello di leggere direttamente dal file utilizzando 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 };
Questa soluzione è efficiente e semplice troppo.
Nota: Se effettivamente si vuole bypassare la cache, ad esempio perché l'immagine può cambiare sul disco, si dovrebbe anche impostare CreateOption = BitmapCreateOption.IgnoreImageCache
. Ma anche in questo caso la soluzione supera la soluzione MemoryStream
perché non tenere due copie dei dati di immagine nella RAM.