2009-02-12 2 views
5

Когда я пытаюсь сохранить ранее загруженный BitmapSource, выдается сообщение System.IO.IOException, в котором говорится, что другой процесс имеет доступ к этому файлу, и этот поток не открывается.Загрузите BitmapSource и сохраните его с использованием того же имени в WPF -> IOException

Если я сохраню без загрузки ранее, все будет хорошо.

Код загрузки:

BitmapImage image = new BitmapImage(); 

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

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

image.EndInit(); 

код Экономия:

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); 
} 

Похоже, после загрузки данных изображения, файл по-прежнему заблокирован и не может быть перезаписана в то время как приложение, открывшая он все еще работает. Есть идеи, как это решить? Большое спасибо за любые решения.

ответ

9

Вдохновленный комментариями, которые я получил по этой проблеме, я решил проблему, прочитав все байты в memystream и используя его в качестве Sreamsource BitmapImage.

Это один работает отлично:

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

Вы взяли комментарии других пользователей, не повышали никого, создали производное решение, которое вы отправили в качестве ответа, и вы дали себе голосование, одобренное Poster-Answer? – hughdbrown

+15

Я новичок в stackoverflow. Как вы можете видеть. Поэтому я просто не могу продвигать других, пока у меня не будет репутации 15. И поскольку другие любезно предоставили хорошие предложения, но не нашли реального решения для людей, имеющих одну и ту же проблему, я сам предоставил ответ в результате моих собственных исследований. Проблема? – sdippl

0

Теперь я не уверен, если это может быть применена к BitmapImage, но я была очень похожая проблема с сохранением измененного изображения к исходному файлу в GDI + here

Метод загрузки изображения из файла держит блокировка открывается в файле до тех пор, пока объект изображения не будет удален.

Возможно, это то же самое с bitmapimage.urisource. Не разыгрывая, вы могли бы скопировать изображение в память и удалить оригинал, открыв таким образом файл?

3

Добавьте следующую строку в код загрузки:

image.CacheOption = BitmapCacheOption.OnLoad; 

Это загрузит открыть файл, прочитать его в память, и закрыть все это во время image.EndInit. По умолчанию BitmapCacheOption.Default имеет странное поведение при открытии файла, считывая его в память, но не закрывая его во время image.EndInit.

+1

Это работает, но вы также должны использовать BitmapCreateOptions.IgnoreImageCache в случае, если вы создаете новый BitmapImage, использующий тот же путь позже в процессе. Это связано с тем, что BitmapImage будет кэшировать данные изображения через экземпляры класса BitmapImage. – manu08

+0

@ manu08: если бы я мог как-то подстегнуть вас за это. Я долго смотрел вокруг и не мог найти решение моей проблемы. При написании моего собственного вопроса SO мне повезло, и мне удалось найти ваш комментарий, и это было именно то, что мне нужно! – Dave

0

Установка CacheOption в BitmapCacheOption.OnLoad, не решит вашу проблему. Я думаю, что есть ошибка, но у меня была та же проблема. Наконец, я загрузил свое изображение в поток памяти и разместил BitmapImage перед сохранением изображения в файле.

+0

На самом деле все работает отлично. Вы должны создать BitmapImage, вызвать BeginInit(), затем установить CacheOption, а затем установить UriSource, затем вызвать EndInit(). –

7

Вот еще одно решение, на основании исходного кода загрузки:

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();