2013-10-10 69 views
14

我有一個C#/。NET程序,我寫的是從磁盤.NET Image.Save偶爾會生成一個PNG一個壞IDAT塊

Bitmap b = Bitmap.FromStream(new MemoryStream(File.ReadAllBytes(filename))) as Bitmap; 

負載PNG圖像對他們進行一些變換(旋轉,縮放,阿爾法),然後用基礎上變換不同的文件名保存生成的PNG圖像回磁盤應用

b.Save(outputName, ImageFormat.Png); 

我已經成功地寫幾千使用工具PNG格式的。但是,偶爾有一個PNG無法加載到使用libpng的單獨程序中。在該程序中,libpng給出錯誤「發現太多IDAT」

調查PNG文件,在IEND塊之前的文件末尾顯示一個'流氓'IDAT塊。一個這樣的IDAT塊(和下面的IEND塊)在十六進制編輯器中看起來像這樣。這些是文件中的最後24個字節。

IDAT: 0x00 0x00 0xFF 0xF4 0x49 0x44 0x41 0x54 0x35 0xAF 0x06 0x1E  
IEND: 0x00 0x00 0x00 0x00 0x49 0x45 0x4e 0x44 0xAE 0x42 0x60 0x82 

IDAT塊長度顯示爲0xFFF4。但是,顯而易見,IDAT塊(或甚至文件中沒有那麼多字節)。

是否有其他人遇到此問題?我可以通過幾種方式之一解決問題。我可以手動編輯PNG文件以刪除最後一個IDAT塊(或將其大小設置爲0.)我可以運行修復損壞的PNG的輔助程序。但是,我想要一個C#/。NET解決方案,我可以輕鬆添加到我的原始程序中。理想情況下,我想要一個解決方案,不需要我重新打開PNG作爲二進制文件;檢查壞IDAT塊;並重新編寫PNG。但是,我開始認爲這是我需要做的。

+0

做你的圖像大小/行步幅有所不同?如果對於被破壞的圖像有獨特的東西(寬度,高度,步幅,格式),你是否能夠縮小範圍? – Chris

+1

我認爲你將不得不更多地隔離問題。如果您使用C#立即讀回您保存的每個文件,您是否可以重新編制錯誤?如果是這樣,你需要追蹤導致這幅破碎圖像的精確環境並從那裏開始。 –

+0

@Chris圖像尺寸和行跨度都在光譜範圍內。它們都是Format32bppArgb。我沒有發現任何關於失敗的PNG的獨特之處。 –

回答

0

這是不是一個真正的完整的答案,因爲我無法重現的圖像。但你可以嘗試加載使用Bitmap構造的另一個形象:

http://msdn.microsoft.com/en-us/library/0cbhe98f.aspx

這將改變你的代碼:

Bitmap b = new Bitmap(filename); 

因爲它們的構造使用了一些機GDI +功能加載圖像進入內存,而不是讀取原始字節:

http://dotnetframework.org/default.aspx/[email protected]/[email protected]/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/CommonUI/System/Drawing/[email protected]/1305376/[email protected]

即使問題出現在將映像寫入磁盤時,也可能有所不同。

+0

感謝您的輸入。但是,我試過其他位圖構造函數,但沒有運氣。我特別選擇了FromStream版本,因爲其他人可以讓文件句柄比我想要的時間更長。 –