Загрузите BitmapSource и сохраните под тем же именем в WPF -> IOException - PullRequest
5 голосов
/ 12 февраля 2009

Когда я пытаюсь сохранить BitmapSource, который я загружал ранее, выдается System.IO.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);
}

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

Ответы [ 5 ]

9 голосов
/ 16 февраля 2009

Вдохновленный комментариями к этой проблеме, я решил эту проблему, прочитав все байты в потоке памяти и использовав его в качестве источника Sreams 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();
}
7 голосов
/ 28 мая 2009

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

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();
3 голосов
/ 13 февраля 2009

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

image.CacheOption = BitmapCacheOption.OnLoad;

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

0 голосов
/ 13 февраля 2009

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

0 голосов
/ 13 февраля 2009

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

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

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

...