在从其构造TransformedBitmap之后释放原始ImageSource

时间:2015-10-22 14:26:41

标签: c# wpf image memory bitmap

背景:

我正在构建一个应用程序,该应用程序将打开可能大量的照片,生成缩略图以呈现给用户,然后允许诸如exif数据查看/清除和次要后期处理之类的事情。 我希望允许用户滚动图像而不会暂停加载每个图像,因为它变得可见,但我也不想在内存中保留数十或数百个全尺寸位图图像。

我使用System.Drawing对象及其Image方法使用GenerateThumbnailImage构建了此任务的原型,但决定转移到WPF并使用System.Windows.Media.ImageSource派生对象和TransformedBitmap ScaledTransform生成缩略图。

但我发现,当我创建TransformedBitmap时,它会有一个返回源图像的引用,该引用可用并仍然存在于内存中。如何发布此源对象?

一些相关的C#代码:

using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
using System;
...
private void LoadImage(){
    //Called by my class internally to handle generating the thumbnail
    //Intent is to keep only metadata and a thumbnail bitmap in memory
    Stream handle = File.OpenRead(FileName);
    BitmapDecoder source = BitmapDecoder.Create(handle,BitmapCreateOptions.None,BitmapCacheOption.OnLoad);
    handle.Dispose();
    //Determine a scaling ratio to force the larger of height or width to fit inside my desired thumbnail size (int)MaxDim.
    ScaleRatio = Math.Min(MaxDim/Math.Max(source.Frames[0].PixelHeight,source.Frames[0].PixelWidth),1); //a public member of the class, Double
    _ImageSource = new TransformedBitmap(source.Frames[0],new ScaleTransform(ScaleRatio,ScaleRatio)); //private member of the class, ImageSource
    _ImageSource.Freeze(); 
    _Exif = source.Frames[0].Metadata; //private member of the class, ImageMetadata
}

这里的问题是,虽然我希望释放(BitmapDecoder)source,但我仍然可以通过_ImageSource.Source访问该对象。

我已经考虑过使用CopyPixels或将TransformedBitmap编码回byte[]流来创建一个新的,希望是未附加的位图,但如果可以的话,这两种方法看起来都是不必要的重新处理只是放弃或处置来源,或者如果有一些简单而快速的方法来创建我尚未发现的浅层克隆。我使用BitmapFrame.Create(TransformedBitmap)尝试使用浅层克隆也没有释放内存,但也没有给我留下明显的参考。

观看内存消耗的一些测试显示每个图像加载成本约为30MB。大约200x200 @ 32bpp图像应该是大约160kB,不计算开销。

问题再次作为TL; DR:如何在TransformedBitmap使用它之后释放对源位图的引用?

0 个答案:

没有答案