Image类的Save方法出错,内存泄漏还是文件独占无法释放?
代码如下:这是一个WPF应用程序,是我在做的一个取色器。
//mw为主窗体
public FullWindow(Window mw)
{
InitializeComponent();
this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
this.Left = 0;
this.Top = 0;
this.MouseDown+=
delegate{
this.Close();
if (mw != null && mw.Visibility == Visibility.Hidden)
mw.Show();
};
double iHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
double iWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
//创建一个和屏幕一样大的bitmap
System.Drawing.Image img = new Bitmap((int)iWidth, (int)iHeight);
//从一个继承自image类的对象中创建Graphics对象
Graphics g = Graphics.FromImage(img);
//抓取全屏幕
g.CopyFromScreen(new System.Drawing.Point(0, 0), new System.Drawing.Point(0, 0), new System.Drawing.Size((int)iWidth, (int)iHeight));
tpath= AppDomain.CurrentDomain.BaseDirectory.Replace(@"bin\Debug", "Images") + "1.bmp";
img.Save(tpath, ImageFormat.Bmp);
//以下代码将img设置为全屏窗体的背景图片。
ImageBrush b = new ImageBrush();
b.ImageSource = new BitmapImage(new Uri(tpath));
b.Stretch = Stretch.Fill;
(b.ImageSource as BitmapImage).CacheOption = BitmapCacheOption.None;
this.Background = b;
if (mw != null&&mw.Visibility==Visibility.Visible)
mw.Hide();
}
现在的问题是,每当第一次运行该窗体时,则不报错,但是关闭该窗体再次打开后,就会在
img.Save(tpath, ImageFormat.Bmp);//此代码处
报错。
另外,Save方法不能使用相对路径吗?迫不得已构造了绝对路径。
帮我看看啊,纠结一下午了! bitmap 图片
[解决办法]
从你的代码看来,应该是取色器的窗体在Close的时候,相关资源并未释放造成的。
首先是System.Drawing.Image?img这里,你缺少了对img的dispose操作,save之后就应该dispose了,后面你再也不会用到那个img对象。
然后是ImageBrush b = new ImageBrush();
b.ImageSource = new BitmapImage(new Uri(tpath));
这里将路径中的文件锁定了,只能读取不能写入,如果Close后并未直接释放其BitmapImage资源(可能被WPF缓存了),就会导致无法修改它了。
你可以在img.Save的时候写入MemoryStream中,然后用这个MemoryStream写入到文件和加载BitmapImage,两不误。
[解决办法]
代码改成如下:
......
System.Drawing.Image img = new Bitmap((int)iWidth, (int)iHeight);
//从一个继承自image类的对象中创建Graphics对象
Graphics g = Graphics.FromImage(img);
//抓取全屏幕
g.CopyFromScreen(new System.Drawing.Point(0, 0), new System.Drawing.Point(0, 0), new System.Drawing.Size((int)iWidth, (int)iHeight));
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Bmp);
ImageBrush b = new ImageBrush();
BitmapImage bp = new BitmapImage();
bp.BeginInit();
bp.StreamSource = ms;
bp.EndInit();
b.ImageSource =bp;
b.Stretch = Stretch.Fill;
this.Background = b;
......