首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

Image种的Save方法出错,内存泄漏还是文件独占无法释放

2013-09-24 
Image类的Save方法出错,内存泄漏还是文件独占无法释放?代码如下:这是一个WPF应用程序,是我在做的一个取色

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;
......

热点排行