【发布时间】:2009-11-14 08:54:05
【问题描述】:
我需要将 WPF 中 Tiff 图像中的所有帧打开到内存中,然后删除源。之后,我最终需要渲染该图像(根据窗口大小调整大小)。我的解决方案很慢,我无法在第一次要求之前删除文件源。有什么最佳做法吗?
【问题讨论】:
标签: wpf memory rendering tiff frames
我需要将 WPF 中 Tiff 图像中的所有帧打开到内存中,然后删除源。之后,我最终需要渲染该图像(根据窗口大小调整大小)。我的解决方案很慢,我无法在第一次要求之前删除文件源。有什么最佳做法吗?
【问题讨论】:
标签: wpf memory rendering tiff frames
使用CacheOption = BitmapCacheOption.OnLoad
此选项可以与BitmapImage.CacheOption 属性一起使用,也可以作为BitmapDecoder.Create() 的参数使用。如果您想在加载图像后访问多个帧,则必须使用BitmapDecoder.Create。在任何一种情况下,文件都将被完全加载并关闭。
另见我对this question的回复
更新
以下代码非常适合加载图像的所有帧并删除文件:
var decoder = BitmapDecoder.Create(new Uri(imageFileName), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
List<BitmapFrame> images = decoder.Frames.ToList();
File.Delete(imageFileName);
当然也可以在文件被删除后访问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 在内存中同时保存两个数据副本:解码副本和未解码副本。
【讨论】:
BitmapCacheOption.Onload 在与BitmapDecoder.Create() 一起使用时确实会加载所有数据并关闭源文件。也许您传递了Stream 并在调用返回后忘记关闭流?也许您忘记在测试中添加OnLoad 选项?也许您使用了new 而不是.Create() 方法?我会用一些确实有效的代码来更新我的答案。
我想通了。我必须使用 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);
【讨论】: