2009-08-04 127 views
2

好吧,我很抱歉,這可能是一個noob問題,但我有點卡住了。從System.Drawing.Image的文件系統上創建一個新的圖像?

所以我在做什麼(在我的asp.net應用程序)加載從文件系統中的圖像:

System.Drawing.Image tempImage; 
tempImage = System.Drawing.Image.FromFile(HttpContext.Server.MapPath(originalPath)); 

然後我做了一些調整大小:

tempImage = my awesomeResizingFunction(tempImage, newSize); 

,並打算將它保存到另一個位置的文件系統使用這個:

string newPath = "/myAwesomePath/newImageName.jpg"; 
tempImage.Save(newPath); 

我得到的是這個錯誤:

"A generic error occurred in GDI+." 

我知道圖像是「OK」,因爲我可以寫出來給瀏覽器,看看調整後的圖像,當我試圖挽救它,我只能得到錯誤。我有點新,並卡住了,我是否完全錯誤? (好吧,我想這很明顯,但你知道我的意思......)

回答

5

PLZ結束時關閉試試這個代碼...我已經使用了相同的代碼調整圖像和保存。如果你有任何問題,然後請讓我知道。

System.Drawing.Bitmap bmpOut = new System.Drawing.Bitmap(NewWidth, NewHeight); 
    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmpOut); 
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
    g.FillRectangle(System.Drawing.Brushes.White, 0, 0, NewWidth, NewHeight); 
    g.DrawImage(new System.Drawing.Bitmap(fupProduct.PostedFile.InputStream), 0, 0, NewWidth, NewHeight); 
    MemoryStream stream = new MemoryStream(); 
    switch (fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.') + 1).ToLower()) 
    { 
     case "jpg": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
      break; 
     case "jpeg": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
      break; 
     case "tiff": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff); 
      break; 
     case "png": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Png); 
      break; 
     case "gif": 
      bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Gif); 
      break; 
    } 
    String saveImagePath = Server.MapPath("../") + "Images/Thumbnail/" + fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.')); 
    bmpOut.Save(saveImagePath); 

其中fupProduct是文件上傳控制ID

+1

您可以通過使用Path.GetExtension而不是IndexOf('。')來改善這一點,儘管您必須稍微修改開關http://msdn.microsoft.com/zh-cn/library/system.io.path .getextension.aspx – RichardOD 2009-09-29 10:45:39

0

是否有可能支持原始圖像的原始流已關閉?如果位圖後面的流已關閉,您將開始獲取GDI +錯誤。當我們將圖像處理添加到我們的網站時,我遇到了很多問題。

如果在Visual Studio調試器中打開Bitmap對象,您是否看到異常而不是屬性的值?如果是這樣,這不是保存操作的問題,但GDI +層失去了處理對象的能力。

我發現我需要跟蹤屬於我的Bitmap的MemoryStream,並將它們放在一起。調整圖像大小導致新的MemoryStream具有新的位圖圖像。

我結束了創建這個簡單的類(這裏修剪一些額外的屬性不需要):

public class UploadedImage : IDisposable 
{ 
    private Bitmap _img = null; 
    private Stream _baseStream = null; 


    /// <summary> 
    /// The image object. This must always belong to BaseStream, or weird things can happen. 
    /// </summary> 
    public Bitmap Img 
    { 
     [DebuggerStepThrough] 
     get { return _img; } 
     [DebuggerStepThrough] 
     set { _img = value; } 
    } 

    /// <summary> 
    /// The stream that stores the image. This must ALWAYS belong to Img, or weird things can happen. 
    /// </summary> 
    public Stream BaseStream 
    { 
     [DebuggerStepThrough] 
     get { return _baseStream; } 
     [DebuggerStepThrough] 
     set { _baseStream = value; } 
    } 

    [DebuggerStepThrough] 
    public void Dispose() 
    { 
     if (Img != null) 
      Img.Dispose(); 

     if (BaseStream != null) 
      BaseStream.Close(); 

     _attached = false; 
    } 
} 

現在,我正在處理上傳到我們網站上的圖像,以及我發現的是,當Asp.Net回收附加到請求的流,所有突然的圖像操作開始翻轉出來。所以,我的解決方案,無論這是否是最好的方法,是將上傳流中的數據複製到我自己的MemoryStream中,從中加載圖像,並將兩者都粘貼到此容器中。無論我從哪個地方創作出新的圖像,我都會將流和圖像放在一起。

我希望這會有所幫助。

編輯:我也有興趣看到你如何做圖像調整大小。這是我如何做我們的片段:

temp = new Bitmap(newWidth, newHeight, PIXEL_FORMAT); 
temp.SetResolution(newHorizontalRes, newVerticalRes); 
gr = Graphics.FromImage(temp); 

// 
// This copies the active frame from 'img' to the new 'temp' bitmap. 
// Also resizes it and makes it super shiny. Sparkle on, mr image dude. 
// 
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight); 
gr.InterpolationMode = InterpolationMode.HighQualityBicubic; 
gr.SmoothingMode = SmoothingMode.HighSpeed; 
gr.PageUnit = GraphicsUnit.Pixel; 
gr.DrawImage(img, rect); 

// 
// Image copied onto the new bitmap. Save the bitmap to a fresh memory stream. 
// 
retval = new UploadedImage(); 
retval.BaseStream = (Stream)(new MemoryStream()); 

temp.Save(retval.BaseStream, ImageFormat.Jpeg); 
retval.Img = temp; 
+0

注意重要的(http://msdn.microsoft.com/en-us/library/system.drawing.aspx)> System.Drawing命名空間中的類是不支持在Windows或ASP.NET服務中使用。 – 2009-10-16 11:28:01

2

你確定originalPath和newPath指向不同的文件?當您使用Image.FromFile時,該文件將保持鎖定狀態,直到您調用圖像上的Dispose,這會導致您提到的異常。你可以加載圖像一樣,而不是:

Image tempImage = null; 
using (FileStream fs = new FileStream(originalPath, FileMode.Open, FileAccess.Read)) 
{ 
    tempImage = Image.FromStream(fs); 
} 
... 

這種做法保證了文件在使用塊

相關問題