【问题标题】:WPF Images not rendering from in-memory sourcesWPF 图像未从内存中的源呈现
【发布时间】:2010-07-03 09:54:54
【问题描述】:

我的应用程序中有一个数据类,它维护一组表示 JPEG 图像的字节数组。定义为:

private ArrayList FrameList = new ArrayList();

我的 Image 对象在渲染一个空白页面时遇到了一些麻烦(并且也花了不少时间来完成它)。当我插入具有 2K 内存字节数组 (byte x[] = { lots of hex values };) 的空白图像时:

FrameList.Insert(currFrame, x);

然后在其上导入 JPEG 文件:

byte[] bytes = File.ReadAllBytes(fspec);
FrameList[currFrame] = bytes;

数组被正确读入内存并存储在 ArrayList 中(由调试器确认)。

但是,我有一个函数来获取图像:

public BitmapImage getCurrPicture()
{
    MemoryStream strm;
    BitmapImage bmp = new BitmapImage();
    strm = new MemoryStream((byte[])FrameList[currFrame-1]);
    bmp.CacheOption = BitmapCacheOption.None;
    bmp.BeginInit();
    bmp.StreamSource = strm;
    bmp.EndInit();
    strm.Close();
    return bmp;
}

被称为:

imgPicB.Source = data.getCurrPicture();

它并不总是呈现。

imgPicB 在我的 XAML 中定义为:

<Image x:Name="imgPicB"
       Width="400"
       Height="300"
       Stretch="Fill"
       VerticalAlignment="Top" />

有趣的是,如果我使用完全相同的 JPEG 设置源并直接将源设置为文件 URI,它会呈现良好。

在 WPF 中使用内存中的 JPEG 图像有什么问题吗?从文件加载时是否执行了一些额外的智能操作(例如自动检测图像类型)?

【问题讨论】:

    标签: c# wpf image xaml jpeg


    【解决方案1】:

    试试这个:

    public BitmapSource GetCurrPicture()
    {
        var bitmapImage = new BitmapImage();
        using (Stream stream = new MemoryStream((byte[])FrameList[currFrame-1]))
        {
            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = stream;
            bitmapImage.EndInit();
            bitmapImage.Freeze();
            return bitmapImage;
        }
    }
    

    这是通过让 WPF 立即使用OnLoad 解码图像,然后在完成后释放对流的引用来实现的。这意味着流可以在离开函数时被垃圾收集。否则,BitmapImage 可能会一直保留到流中,直到它被渲染。

    在问题中发布的代码中,渲染会失败,因为:

    • 解码延迟;和
    • 流已在尝试解码时关闭。

    【讨论】:

    • 好的,我试一试,但是为什么?您认为是使用还是冻结有帮助?
    • 不,是BitmapCacheOption.OnLoad。至于using,这只是一个好习惯。
    • 谢谢,达林,这很好。然而,问题是,我仍然不确定为什么。是不是因为内存中的流没有支持“文件”,特别是因为我在创建位图后关闭了流?
    • 这回答了您的问题吗? stackoverflow.com/questions/1733730/…立即将图片加载到内存中
    • @paxdiablo:你回答了你自己的问题。
      Darin 的解决方案确保 WPF 将立即解码图像 (OnLoad) 并在完成后释放对流的引用。这意味着流可以在离开函数时被垃圾收集。否则,BitmapImage 可以保留流直到它被渲染。在您的代码中,渲染将失败,因为流已关闭。
    【解决方案2】:

    http://blogs.msdn.com/b/dwayneneed/archive/2008/06/20/implementing-a-custom-bitmapsource.aspx

    DwayneNeed 2008 年 6 月 20 日下午 5:11 Comments

    • 缓存
      BitmapImage 将解码的位图存储在系统内存中。您可以通过设置CacheOption 属性来控制何时发生这种情况。 BitmapImage 还维护先前 BitmapImage 实例的缓存(通过弱引用),以便多次加载同一个 Uri 将共享同一个实例。为避免此缓存,您可以在 CreateOptions 属性中包含 BitmapCreateOptions.IgnoreImageCache 标志。

    【讨论】:

      猜你喜欢
      • 2015-05-19
      • 2019-12-07
      • 2020-11-10
      • 2015-06-16
      • 1970-01-01
      • 2014-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多