2009-07-30 51 views
0

我想在C#中使用MVC框架創建一個實用工具,用戶上傳的圖片用於裁剪出用作縮略圖圖標的圖片(只有一個用戶在任何時候都會這樣做)。用戶然後可以上傳不同的圖片並繼續裁剪。無法用C#使用Image對象覆蓋上傳的圖像

我有一個控制器操作,處理文件上傳拍攝照片,將其從任何格式轉換爲JPEG並將其保存爲「temp.jpg」(我知道這不是一個瘦控制器,但這只是用於測試目的)。當他們上傳下一張圖片時,我想用這張新圖片替換temp.jpg。此控制器可以在我的機器上正常開發,但在用戶上傳第一張圖像並試圖用另一張圖像替換之後,它們會出現以下錯誤:

「該進程無法訪問該文件,因爲它正在被使用通過另一個進程「

在我看來,」temp.jpg「文件在第一次上傳後被鎖定,我無法弄清楚如何避免這種情況。

歡迎任何建議或替代想法。

打破我的代碼做什麼了下來:

  • 檢查,如果要上傳的圖片 存在於服務器上,如果發現
  • 保存的圖片作爲與 它的原始文件名,並刪除它如果發現
  • 打開在爲System.Drawing.Image對象的原始圖像轉換到jpeg擴展
  • 檢查爲「temp.jpg」文件並刪除它
  • 將其另存爲新的「temp.jpg」以替換已刪除的文件。

我的代碼: 「temp.jpg」

 [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult PicUpload(DateTime sd, FormCollection collection) 
    { 
      foreach (string file in Request.Files) 
      { 
       HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase; 
        if (hpf.ContentLength == 0) 
         continue; 
        string savedFileName = Path.Combine(
         AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\", 
         Path.GetFileName(hpf.FileName)); 

        FileInfo temp = new FileInfo(savedFileName); 
        if (temp.Exists) temp.Delete(); 

        hpf.SaveAs(savedFileName); 

        string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg"; 

        temp = new FileInfo(tempFileName); 
        if (temp.Exists) temp.Delete(); 

        EncoderParameters codecParams = new EncoderParameters(1); 
        codecParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L); 
        ImageCodecInfo[] encoders; 
        encoders = ImageCodecInfo.GetImageEncoders(); 

        Image newPic = Image.FromFile(savedFileName); 
        newPic.Save(tempFileName, encoders[1], codecParams); 
        newPic.Dispose(); 

        FileInfo tmp = new FileInfo(savedFileName); 
        if (tmp.Exists) tmp.Delete(); 
        return RedirectToAction("Create", new { startdate = String.Format("{0:MM-dd-yyyy}", sd) }); 
      } 
      return RedirectToAction("Create", new { startdate = String.Format("{0:MM-dd-yyyy}", sd) }); 
    } 

回答

2

事實證明,我並沒有在我的代碼的另一部分中正確釋放圖像的資源,這部分代碼正在返回圖像的寬度和高度屬性。此外,而不是使用Dispose();方法,我把代碼變成了「使用塊」,而不是像這樣:

  using (Image newPic = Image.FromFile(savedFileName)) 
      { 
       newPic.Save(tempFileName, encoders[1], codecParams); 
      } 

這工作就像一個魅力,現在我可以刪除肆無忌憚地temp.jpg文件。

0

您可以使用一個唯一命名的臨時文件爲tempFileName,而不是System.IO.Path有一個可用於此的GetTempFileName()方法。

另一種選擇是使用GetRandomFileName()方法(也System.IO.Path),它返回一個隨機路徑或文件名,那麼它只是一個做一個小的改變了代碼的事情:

- string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg"; 
+ string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\" + System.IO.Path.GetRandomFileName(); 
+0

這可能工作,雖然我不得不保存的文件名,並有我的視圖中引用它。 – hotbot86 2009-07-30 22:28:51

+0

這很可能是你最終必須做的。 – 2009-07-30 22:39:55

1

System.Drawing中.Image.Save()無法保存到打開文件的相同位置:

the docs:「將圖像保存到它所構建的同一文件是不允許的,並引發異常。

1

使用「面板」控制,並將其保存爲BMP,PNG,無論