Мне нужно открыть все кадры из изображения Tiff в WPF в память, а затем удалить источник. И после этого мне в конечном итоге нужно отобразить это изображение (измененное в соответствии с размером окна). Мое решение довольно медленное, и я не могу удалить источник файла до первого запроса. Любые лучшие практики?Загрузить изображение в память сразу
ответ
Использование CacheOption = BitmapCacheOption.OnLoad
Эта опция может быть использована с BitmapImage.CacheOption
собственности или в качестве аргумента BitmapDecoder.Create()
Если вы хотите получить доступ к несколько кадров, как только изображение загружается вы должны использовать BitmapDecoder.Create
. В любом случае файл будет загружен полностью и закрыт.
Смотрите также мой ответ на this question
Update
Следующий код работает отлично для загрузки во всех кадров изображения и удаления файла:
var decoder = BitmapDecoder.Create(new Uri(imageFileName), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
List<BitmapFrame> images = decoder.Frames.ToList();
File.Delete(imageFileName);
Вы можете также access decoder.Frames после удаления файла, конечно.
Этот вариант также работает, если вы хотите открыть потока себя:
List<BitmapFrame> images;
using(var stream = File.OpenRead(imageFileName))
{
var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
images = decoder.Frames.ToList();
}
File.Delete(imageFileName);
В любом случае, это более эффективно, чем создание MemoryStream
, поскольку MemoryStream
хранит две копии данных в памяти сразу: декодированной копии и незакодированной копии.
Я понял. Я должен использовать MemoryStream:
MemoryStream ms = new MemoryStream(File.ReadAllBytes(image));
TiffBitmapDecoder decoder = new TiffBitmapDecoder(ms, BitmapCreateOptions.None, BitmapCacheOption.None);
List<BitmapFrame> images = new List<BitmapFrame>();
foreach (BitmapFrame frame in decoder.Frames) images.Add(frame);
Это неэффективно, потому что одновременно хранит две копии файла в памяти: MemoryStream и данные в BitmapFrames. Мой ответ достигает того же результата более эффективно, и он действительно работает. –
Спасибо, но как я могу получить доступ к нескольким кадрам изображения в объекте BitmapImage? –
Вы можете использовать BitmapDecoder.Create(), тогда вы можете получить все фреймы. Я добавил абзац к моему ответу, чтобы объяснить это. –
В настоящее время я это делаю, я просто не знаю, как преобразовать BitmapFrame в BitmapImage. После копирования всех кадров в список Я не могу удалить файл изображения. Мне нужно просто удалить файл изображения сразу после загрузки всех кадров в память. –