2009-02-12 11 views
5

Quando provo a salvare un BitmapSource che ho caricato in precedenza, viene lanciato un System.IO.IOException che indica che un altro processo sta accedendo a quel file e non è possibile aprire il filestream.Carica un BitmapSource e salva usando lo stesso nome in WPF -> IOException

Se salvo solo il caricamento precedente, tutto funziona correttamente.

Il codice di carico:

BitmapImage image = new BitmapImage(); 

image.BeginInit(); 
image.UriSource = uri; 

if (decodePixelWidth > 0) 
image.DecodePixelWidth = decodePixelWidth; 

image.EndInit(); 

il codice risparmio:

using (FileStream fileStream = new FileStream(Directory + "\\" + FileName + ".jpg", FileMode.Create)) 
{ 
    JpegBitmapEncoder encoder = new JpegBitmapEncoder(); 
    encoder.Frames.Add(BitmapFrame.Create((BitmapImage)image)); 
    encoder.QualityLevel = 100; 
    encoder.Save(fileStream); 
} 

Sembra che dopo il caricamento dei dati di immagine, il file è ancora bloccato una non può mai essere sovrascritto mentre l'applicazione che ha aperto è ancora in esecuzione. Qualche idea di come si possa risolvere? Grazie mille per qualsiasi soluzione.

risposta

9

Ispirato dai commenti che ho ricevuto su questo problema, ho risolto il problema leggendo tutti i byte in un memorystream e utilizzandolo come Sreamsource di BitmapImage.

Questo funziona perfettamente:

if (File.Exists(filePath)) 
{ 
    MemoryStream memoryStream = new MemoryStream(); 

    byte[] fileBytes = File.ReadAllBytes(filePath); 
    memoryStream.Write(fileBytes, 0, fileBytes.Length); 
    memoryStream.Position = 0; 

    image.BeginInit(); 
    image.StreamSource = memoryStream; 

    if (decodePixelWidth > 0) 
     image.DecodePixelWidth = decodePixelWidth; 

    image.EndInit(); 
} 
+0

Hai preso i commenti degli altri, non hai rivoluzionato nessuno, hai creato una soluzione derivata che hai postato come risposta e ti sei dato il voto di risposta con approvazione Poster? – hughdbrown

+15

Sono nuovo nello stackoverflow. Come puoi vedere Quindi non posso invitare altri fino a quando non avrò una reputazione di 15. E poiché gli altri gentilmente hanno fornito buoni suggerimenti, ma nessuna vera soluzione per le persone che hanno lo stesso problema, ho fornito la risposta io stesso come risultato della mia stessa ricerca. Problema? – sdippl

0

Ora io non sono sicuro se questo può essere applicato a BitmapImage, ma ho avuto un problema molto simile con il salvataggio di un immagine modificata al file originale in GDI + here

Il metodo di caricamento dell'immagine da file mantiene un bloccare il file finché l'oggetto immagine non viene eliminato.

Forse è la stessa cosa con bitmapimage.urisource. Senza giocare potresti copiare l'immagine in memoria e disporre l'originale sbloccando così il file?

3

Aggiungere la seguente riga al codice di carico:

image.CacheOption = BitmapCacheOption.OnLoad; 

Questo caricherà aprire il file, leggerlo in memoria, e chiuderlo tutti durante image.EndInit. L'impostazione predefinita di BitmapCacheOption.Default ha lo strano comportamento di aprire il file, leggerlo in memoria, ma non ancora chiuderlo durante l'immagine .EndInit.

+1

Questo funziona, ma è anche necessario utilizzare BitmapCreateOptions.IgnoreImageCache nel caso in cui si crea una nuova BitmapImage che utilizza lo stesso percorso più avanti nel processo. Questo perché BitmapImage memorizzerà nella cache i dati dell'immagine tra istanze della classe BitmapImage. – manu08

+0

@ manu08: se solo potessi invitarvi per questo in qualche modo. Ho passato molto tempo a guardarmi intorno e non sono riuscito a trovare la soluzione al mio problema. Mentre scrivevo la mia domanda SO, sono stato fortunato e ho trovato il tuo commento, ed era esattamente ciò di cui avevo bisogno! – Dave

0

L'impostazione di CacheOption su BitmapCacheOption.OnLoad non risolverà il problema. Penso che ci sia un bug, ma ho avuto lo stesso problema. Alla fine ho caricato la mia immagine su un flusso di memoria e ho sistemato BitmapImage prima di salvare l'immagine nel file.

+0

In realtà funziona bene per me. Devi creare BitmapImage, chiamare BeginInit(), quindi impostare CacheOption, quindi impostare UriSource e chiamare EndInit(). –

7

Ecco un'altra soluzione, in base al codice di carico originale:

var image = new BitmapImage(); 
image.BeginInit(); 

// overwrite cache if already exists, to refresh image 
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache; 
// load into memory and unlock file 
image.CacheOption = BitmapCacheOption.OnLoad; 

image.UriSource = uri; 
if (decodePixelWidth > 0) image.DecodePixelWidth = decodePixelWidth; 
image.EndInit(); 
Problemi correlati