GDI+ 中发生一般性错误:释放文件句柄

今天在压缩商城的图片是,领略到释放资源的重要性。尤其是在操作文件时,如果不及时释放对文件的访问权,就会导致错误。

在压缩完图片,尝试覆盖原图片时,系统提示:GDI+ 中发生一般性错误。

Google了一下,得到3中可能性:

在开发.NET应用中,使用 System.Drawing.Image.Save 方法而导致“GDI+ 中发生一般性错误”的发生,通常有以下三种原因:
1. 相应的帐户没有写权限。
解决方法:赋予 NETWORK SERVICE 帐户以写权限。
2. 指定的物理路径不存在。
解决方法:
在调用 Save 方法之前,先判断目录是否存在,若不存在,则创建。
if (!Directory.Exists(dirpath))
Directory.CreateDirectory(dirpath);
3. 保存的文件已存在并因某种原因被锁定。
解决方法:
重启IIS,解除锁定。并在代码中使用 using 语句,确保释放 Image 对象所使用的所有资源。

根据猜想,估计是第三种。那么就是资源没有释放啦。在swfupload这个项目的samples中有一个.net生成缩略图的例子,而我,正是照着这个例子来做的。仔细看了它的代码,发现它还有一个释放资源的try...catch...finally语句。

下面是我最后改好的例子:

    private string FixPic2(string pic)
    {
        if (!System.IO.File.Exists(pic))
            return null;

        System.Drawing.Image image = System.Drawing.Image.FromFile(pic);
        if (image != null)
        {
            if (image.Width > 220 || image.Height > 220)
            {
                System.Drawing.Bitmap final_image = null;
                System.Drawing.Graphics graphic = null;
                try
                {
                    System.IO.File.Copy(pic, pic + ".bak", true);

                    int width = image.Width;
                    int height = image.Height;
                    int target_width = 220;
                    int target_height = 220;
                    int new_width, new_height;

                    float target_ratio = (float)target_width / (float)target_height;
                    float image_ratio = (float)width / (float)height;

                    if (target_ratio > image_ratio)
                    {
                        new_height = target_height;
                        new_width = (int)Math.Floor(image_ratio * (float)target_height);
                    }
                    else
                    {
                        new_height = (int)Math.Floor((float)target_width / image_ratio);
                        new_width = target_width;
                    }

                    new_width = new_width > target_width ? target_width : new_width;
                    new_height = new_height > target_height ? target_height : new_height;



                    final_image = new System.Drawing.Bitmap(target_width, target_height);
                    graphic = System.Drawing.Graphics.FromImage(final_image);
                    graphic.FillRectangle(new System.Drawing.SolidBrush(System.Drawing.Color.White), new System.Drawing.Rectangle(0, 0, target_width, target_height));
                    int paste_x = (target_width - new_width) / 2;
                    int paste_y = (target_height - new_height) / 2;
                    graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; /* new way */
                    //graphic.DrawImage(thumbnail_image, paste_x, paste_y, new_width, new_height);
                    graphic.DrawImage(image, paste_x, paste_y, new_width, new_height);

                    image.Dispose();
                    //string newFileName = System.IO.Path.GetDirectoryName(Server.MapPath(pic)) + "/" + System.IO.Path.GetFileNameWithoutExtension(pic) + "_s" + System.IO.Path.GetExtension(pic);

                    final_image.Save(pic, System.Drawing.Imaging.ImageFormat.Jpeg);

                    Response.Write("

Fix OK--:" + pic + "

"); Response.Flush(); //return System.IO.Path.GetDirectoryName(pic).Replace("\\", "/") + "/" + System.IO.Path.GetFileNameWithoutExtension(pic) + "_s" + System.IO.Path.GetExtension(pic); } catch (Exception ex) { Response.Write(ex.ToString()); } finally { if (final_image != null) final_image.Dispose(); if (graphic != null) graphic.Dispose(); if (image != null) image.Dispose(); } } } return null; }

 try...catch....finally机制用来释放资源,以保证文件可以在下一次正常调用。

参考链接:http://www.cnblogs.com/wudingfeng/archive/2008/07/24/1250564.html

本文首发:剑锋博客 尊重作者,请保留链接。

分享到: 更多

给我留言(您的留言,是对我最好的鼓励!

公告栏

  • 姓名:林剑锋(不见不散)
  • 来自:中国-广州
  • 简介:潮汕人,出生于广东揭西。醉心于Web开发8年,挑战了一年整体策划和网站运营。目前就职于平成混媒IT部。
  • Email/QQ:admin@ljf.cn

QQ群:设计学院 68075618,网站设计师 9908776

统计

文章:335篇
评论:163条 (2条Spam)
相册:1个 (120张图片)
主题:Nagrand新主题

www.ljf.cn网站PR查询