前言
記得「 Image.Save(stream,format.png) GDI+ generic error」這個錯誤在好久之前有看到過,但一直沒有注意那時是如何解決的。
今天同事有再詢問,所以就將網路上的資料一併記錄一下。
研究
網路上有的人說因為原本的 Image 被 Lock 住了,或是要 避免使用原本的 Stream 去 Save。
例如 Rick 的範例, 建立 bm2 後,再把 bm2 Save 到 Stream 去,就有可能會 GG。
1 | Bitmap bm2 = this.GetGlobalResourceObject("Resources", "_BitMap") as Bitmap; |
我們公司的程式,在某些機器上才會出現錯誤,如下,
1 | /// <summary> |
1 | image.Save(byteStream, sourceFileFormat); |
上面 image.Save 在某些狀況下會出錯,或許可以新增一個 Bitmap 物件來 Save ,如下,
1 | for (int p = 0; p < page; p++) |
現況
雖然程式上去了,但在 IIS 運行一段時間後,又出現了 GDI+ 的錯誤。iisreset 後又可以了。
查看有問題的 png ,高度也沒太高,w3wp.exe 也沒有吃到很高的 Memory 。
在查不到任何頭緒之下,想到 png 只有一頁而已,原本的程式碼應該是針對 Tiff 來處理分頁的。
而讀進來的 Byte Array 本身就是 Image 了,就不需要特別再將它轉再 Image 又再轉回 Byte Array。
直接將傳進來的 Byte Array 直接轉 Base64 字串出去就可以了。
測試的程式如下,
- 原本的程式
1 | public string[] GetPngFiles(string[] pngPaths) |
- 調整後的程式
1 | public string[] GetPngFiles2(string[] pngPaths) |
- 註: 後來那個 GDI+ 又出現在 Aspose 的套件中,而且奇怪的是發生後,需要「重新開機」才又可以使用,過個 2 天,又會出現,所以與同事持續關注中,有新的狀況會再跟大家 Update。
有看了一下網路上的可能問題,
- 讀檔權限不足
- 沒有 Dispose
- 在使用前,已被 Dispose 掉了。
參考資料
Common Problems with rendering Bitmaps into ASP.NET OutputStream
Bitmap.save(): A generic error occurred in GDI+
asp.net : A generic error occurred in GDI+
Image.SelectActiveFrame memory problem
A generic error occurred in GDI+, JPEG Image to MemoryStream