【问题标题】:Load image into memory immediately立即将图像加载到内存中
【发布时间】:2009-11-14 08:54:05
【问题描述】:

我需要将 WPF 中 Tiff 图像中的所有帧打开到内存中,然后删除源。之后,我最终需要渲染该图像(根据窗口大小调整大小)。我的解决方案很慢,我无法在第一次要求之前删除文件源。有什么最佳做法吗?

【问题讨论】:

    标签: wpf memory rendering tiff frames


    【解决方案1】:

    使用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 在内存中同时保存两个数据副本:解码副本和未解码副本。

    【讨论】:

    • 谢谢,但是如何访问 BitmapImage 对象中的多帧图像?
    • 你可以使用BitmapDecoder.Create(),然后你可以得到所有的帧。我在答案中添加了一段来解释这一点。
    • 我目前正在这样做,我只是不知道如何将 BitmapFrame 转换为 BitmapImage。将所有帧复制到 List 后,我无法删除图像文件。我只需要在所有帧加载到内存后立即删除图像文件。
    • 我想你一定是搞错了。 BitmapCacheOption.Onload 在与BitmapDecoder.Create() 一起使用时确实会加载所有数据并关闭源文件。也许您传递了Stream 并在调用返回后忘记关闭流?也许您忘记在测试中添加OnLoad 选项?也许您使用了new 而不是.Create() 方法?我会用一些确实有效的代码来更新我的答案。
    【解决方案2】:

    我想通了。我必须使用 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 中的数据。我的回答更有效地实现了相同的结果,而且它真的确实有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 2020-10-23
    • 2017-05-22
    • 1970-01-01
    相关资源
    最近更新 更多