【问题标题】:C# image crop resize deleteC#图像裁剪调整大小删除
【发布时间】:2013-02-05 05:05:48
【问题描述】:

当我尝试使用 System.IO.File.Delete(....) 删除图像时,我得到错误异常。

IOException was unhandled by user code

进程无法访问文件 'xxx\image\6132_15658422-b0a1-45a9-b0f9-7e9af783ad53_Temp.jpg' 因为 它正被另一个进程使用。

有人可以给我建议吗?



我用 c# 裁剪、调整大小和删除图像的主要功能。

    int X1 = 70, Y1 = 20, X2 = 201, Y2 = 236, w = 800, h = 600;
    string filelocation = "image/6132_15658422-b0a1-45a9-b0f9-7e9af783ad53_Temp.jpg";

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            using (System.Drawing.Image _Image = cropImage(
                                                ResizeImage(
                                                        System.Drawing.Image.FromFile( Server.MapPath("~") +"/"+  filelocation), w, h),
                                                        (new System.Drawing.Rectangle(X1, Y1, X2, Y2))))
            {
                _Image.Save(Server.MapPath("~") + "/" + "image/output.jpg");

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally {
            File.Delete(Server.MapPath("~") + "/" + filelocation);
        }
    }

对于裁剪图像功能,

    public System.Drawing.Image cropImage(System.Drawing.Image image, Rectangle cropArea)
    {
        try
        {
            Bitmap bmpImage = new Bitmap(image);
            Bitmap bmpCrop = bmpImage.Clone(cropArea,
            bmpImage.PixelFormat);
            return (System.Drawing.Image)(bmpCrop);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

对于调整图像大小功能,

    public System.Drawing.Image ResizeImage(System.Drawing.Image image, int maxWidth, int maxHeight)
    {
        try
        {
            var ratioX = (double)maxWidth / image.Width;
            var ratioY = (double)maxHeight / image.Height;
            var ratio = Math.Min(ratioX, ratioY);

            var newWidth = (int)(image.Width * ratio);
            var newHeight = (int)(image.Height * ratio);

            var newImage = new Bitmap(newWidth, newHeight);
            Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);

            return newImage;
        }
        catch (Exception ex)
        {
            throw ex;
        }

    }

[更新]

最后我按照@landenedge 的建议纠正了我的问题,

          using (var mainImage = System.Drawing.Image.FromFile(Server.MapPath("~") +"/"+  filelocation)){
                using (System.Drawing.Image _Image = cropImage(
                                                    ResizeImage(mainImage, w, h),
                                                            (new System.Drawing.Rectangle(X1, Y1, X2, Y2))))
                {
                    _Image.Save(Server.MapPath("~") + "/" + "image/output.jpg");

                }
            }

【问题讨论】:

  • 提示:“它正被另一个进程使用” ....
  • 是的,但我不知道已经使用了哪个进程...
  • 可能是你自己的:运行 ProcessMonitor ...它是免费的
  • 您正在创建 Bitmap 的新实例,但不会处理您打开的实例。您需要在从现有实例创建新实例后执行此操作。

标签: c# multithreading io


【解决方案1】:

即使在您匹配了所有Dispose() 语句后,您仍会发现问题仍然存在。 Image.FromFile 在任何大容量网站中都是有问题的。解决方案是改用Image.FromStream

   using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
   {
     using (Image original = Image.FromStream(fs))
     {
      ...

使用显式 Dispose()using() 语句或将值设置为 null 在垃圾回收发生之前无法解决问题。强制进行垃圾回收通常是个坏主意。

【讨论】:

  • 关于 Image.FromFile 与 Image.FromStream 的重要建议,感谢@Ian Mercer
【解决方案2】:

您需要处理您使用FromFile() 创建的Image。试试这样的:

using (var mainImage = Image.FromFile(Server.MapPath("~") +"/"+  filelocation), w, h))
using (var _Image = cropImage(ResizeImage(mainImage, new Rectangle(X1, Y1, X2, Y2))))
{
    _Image.Save(Server.MapPath("~") + "/" + "image/output.jpg");
}

另外,不要使用throw ex; 重新引发异常 - 这样做会重置堆栈跟踪并可能丢弃有价值的调试信息。相反,只需使用throw;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多