GDI+中發生一般性錯誤的解決辦法


 

今天在開發.net引用程序中,需要System.Drawing.Image.Save 創建圖片,debug的時候程序一切正常,可是發布到IIS后缺提示出現“GDI+中發生一般性錯誤”的異常。
於是開始“擺渡”,並尋找到了解決辦法:賦予 NETWORK SERVICE 帳戶以寫權限。

以下為晚上尋找到的資料:

在開發.NET應用中,使用 System.Drawing.Image.Save 方法而導致“GDI+ 中發生一般性錯誤”的發生,通常有以下三種原因:
1. 相應的帳戶沒有寫權限。
解決方法:賦予 NETWORK SERVICE 帳戶以寫權限。
2. 指定的物理路徑不存在。
解決方法:
在調用 Save 方法之前,先判斷目錄是否存在,若不存在,則創建。
if (!Directory.Exists(dirpath))
Directory.CreateDirectory(dirpath);
3. 保存的文件已存在並因某種原因被鎖定。
解決方法:
重啟IIS,解除鎖定。並在代碼中使用 using 語句,確保釋放 Image 對象所使用的所有資源。

我遇到的情況:
      在編寫Chem.NET的時候要保存圖片,我先用openFileDialog打開圖片文件,然后用saveFileDialog保存文件時就出現了 “GDI+中發生一般性錯誤”, 我當時就想到是打開的文件還沒有釋放出來,於是用openFileDialog1.Dispose()來釋放,可是沒有成功。同樣從一個 MemorySream 實例打開一個Image后,立即關閉了這個流,結果在Image.Save時也會發生這種錯誤。我“擺渡”了很久都是遇到和我一樣問題的人,CSDN上面 的同志也沒有給出一個實用的答案。最后終於還是在微軟的網站上找到了答案:(以下是官方解決辦法)
症狀
Bitmap 對象或一個 圖像 對象從一個文件, 構造時該文件仍保留鎖定對於對象的生存期。 因此, 無法更改圖像並將其保存回它產生相同的文件。

替代方法
•    創建非索引映像。
•    創建索引映像。
這兩種情況下, 原始 位圖 上調用 Bitmap.Dispose() 方法刪除該文件上鎖或刪除要求, 流或內存保持活動。

創建非索引圖像
即使原始映像被索引格式中該方法要求新圖像位於每像素 (超過 8 位 -) -, 非索引像素格式。 此變通方法使用 Graphics.DrawImage() 方法來將映像復制到新 位圖 對象:
1.    構造從流、 從內存, 或從文件原始 位圖 。
2.    創建新 位圖 的相同大小, 帶有是超過 8 位 - - 像素 (BPP) 每像素格式。
3.    使用 Graphics.FromImage() 方法以獲取有關二 位圖 Graphics 對象。
4.    用於 Graphics.DrawImage() 繪制首 位圖 到二 位圖 。
5.    用於 Graphics.Dispose() 處置是 圖形 。
6.    用於 Bitmap.Dispose() 是首 位圖 處置。

創建索引映像
此解決辦法在索引格式創建一個 Bitmap 對象:
1.    構造從流、 從內存, 或從文件原始 位圖 。
2.    創建新 位圖 具有相同的大小和像素格式作為首 位圖 。
3.    使用 Bitmap.LockBits() 方法來鎖定整個圖像對於兩 Bitmap 對象以其本機像素格式。
4.    使用 Marshal.Copy 函數或其他內存復制函數來從首 位圖 復制到二 位圖 圖像位。
5.    使用 Bitmap.UnlockBits() 方法可以解鎖兩 Bitmap 對象。
6.    用於 Bitmap.Dispose() 是首 位圖 處置。


由於外國人的思維和我們不一樣,我重新用實例解釋一下,我這里使用的是創建非索引圖像。
private void ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                //創建一個bitmap類型的bmp變量來讀取文件。
                Bitmap bmp = new Bitmap(openFileDialog1 .FileName );
                //新建第二個bitmap類型的bmp2變量,我這里是根據我的程序需要設置的。
                Bitmap bmp2 = new Bitmap(1024, 768, PixelFormat.Format16bppRgb555);
                //將第一個bmp拷貝到bmp2中
                Graphics draw = Graphics.FromImage(bmp2);
                draw.DrawImage(bmp,0,0);
                pictureBox1.Image = (Image)bmp2 ;//讀取bmp2到picturebox
                FILE = openFileDialog1.FileName;
                openFileDialog1.Dispose();
                draw.Dispose();
                bmp.Dispose();//釋放bmp文件資源
            }
        }
通過以上的讀取文件,在保存的時候就不會出現錯誤了。

 

轉自:http://blog.sina.com.cn/s/blog_62078285010192cp.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM