背景:
我正在构建一个应用程序,该应用程序将打开可能大量的照片,生成缩略图以呈现给用户,然后允许诸如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使用它之后释放对源位图的引用?