在WPF中使用BitmapImage
为Image
控件的Source
属性赋值时,有时会遇到文件资源被锁定的问题,这会导致尝试删除或修改源图像文件时出现异常。这是因为BitmapImage
默认会保持对底层文件句柄的锁定,直到BitmapImage
对象本身被释放。
为了避免这种情况,可以在加载图像后立即释放文件句柄。这可以通过设置BitmapImage
的CacheOption
属性来实现,具体来说是将其设置为BitmapCacheOption.OnLoad
。这个选项会让BitmapImage
在加载完成之后就立即缓存位图数据,并且释放原始文件句柄。
原代码:
cs
imgjpg.ImageSource = new BitmapImage(new Uri(path));
其中path为图像的原始路径。
问题描述:
在使用BitmapImage给Image的Source赋值时,如果不及时释放图像资源,那么会一直占用资源,如果此时操作原图像,那么很可能就会出现错误。从而导致程序崩溃。
错误信息:
捕捉到 System.Runtime.InteropServices.ExternalException
HResult=-2147467259
Message=GDI+ 中发生一般性错误。
Source=System.Drawing
ErrorCode=-2147467259
StackTrace:
在 System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
在 System.Drawing.Image.Save(String filename, ImageFormat format)
转换图像为BitmapImage,然后关闭图像文件并释放占用图像资源;
代码如下:
cs
public static BitmapImage GetImage(string imagePath)
{
BitmapImage bitmap = new BitmapImage();
if (File.Exists(imagePath))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
using (Stream ms = new MemoryStream(File.ReadAllBytes(imagePath)))
{
bitmap.StreamSource = ms;
bitmap.EndInit();
bitmap.Freeze(); // 在这里释放资源
}
}
return bitmap;
}
调用方法:
cs
image1.Source = GetImage(path); // path为图片路径
请注意,BitmapImage的Freeze方法会将资源从垃圾收集器中释放,因此不会对应用程序的内存使用造成负担。不过请注意,在使用Image控件的时候,最好能及时释放资源,避免造成内存泄露。