2012-12-04 68 views
2

我正在使用Delphi 7,並且必須從我的Delphi應用程序中嵌入的FlashMovie生成大量位圖。 圖片的定義是1010x720。生成位圖時會生成全黑位

當我生成超過6000張照片時(每次都會有所不同),我得到一個EOutOfResources異常。 我環顧四周,似乎它可能來自缺乏可用的句柄。

下面是代碼:

var 
FFlashPlayerControlExport:TFlashPlayerControl; 
Bmp:TBitmap; 
pPNG:TPNGObject; 

begin 
Bmp := FFlashPlayerControlExport.CreateFrameBitmap; 
Bmp.Width := StrToInt(aArgs[5]); 
Bmp.Height := StrToInt(aArgs[6]); 

pPNG := TPNGObject.Create; 
pPNG.Assign(Bmp); 
pPNG.SaveToFile(sFileName); 
pPNG.Free; 

DeleteObject(Bmp.Handle); 
Bmp.Free; 
end; 

我試圖CloseHandle的(Bmp.Handle)剛剛Bmp.Free之前,但我發現了一個EExternalException。

謝謝大家的幫助!


UPDATE 2012年12月6日:

由於Arioch'The的答案,我試圖設置寬度和FFlashPlayerControlExport的高度,而不是直接使用Bmp.Width和Bmp.Height 的它幫助,因爲現在我不會得到EOutOfResources異常,但CreateFrameBitmap會在一段時間後保存全黑圖片。

FlashPlayerControl仍在運行,因爲我在屏幕上看到了圖片。

代碼更新:

var 
FFlashPlayerControlExport:TFlashPlayerControl; 
Bmp:TBitmap; 
pPNG:TPNGObject; 

begin 
FFlashPlayerControlExport.Width := StrToInt(aArgs[5]); 
FFlashPlayerControlExport.Height := StrToInt(aArgs[6]); 

Bmp := FFlashPlayerControlExport.CreateFrameBitmap; 

pPNG := TPNGObject.Create; 
pPNG.Assign(Bmp); 
pPNG.SaveToFile(sFileName); 
pPNG.Free; 

Bmp.Free; 
end; 

UPDATE 2012年12月20日:

的FlashPlayerControl developper團隊接觸後,我發現,當應用達到10.000 GDI對象的位圖變成黑色。 他們提供了一個有效的幫助,我的問題,聯繫他們是有效的:)

我最終發現,GDI對象泄漏來自我的代碼的另一個平行部分。 此主題已關閉:)

+0

您可以嘗試添加[ReportMemoryLeaksOnShutdown](http://docwiki.embarcadero.com/Libraries/XE3/en/System.ReportMemoryLeaksOnShutdown)...在引發異常之前...您關閉應用程序並檢查是否你有任何內存泄漏和什麼樣的對象不_free _... – Whiler

+0

對於一般的處理泄漏請參考此問題:http://stackoverflow.com/questions/2180345/hunting-down-eoutofresources –

+0

該代碼看起來乾淨。當然你應該使用try/finally。不要調用'DeleteObject'。讓這件事發生在'TBitmap'析構函數中。還有其他東西在泄漏。 –

回答

0

當由TBitmap創建的句柄被錯誤代碼使用時,可能無法正確清理句柄。此句柄泄漏累積並且在幾次這樣泄漏GetDC開始失敗。

EOutOfResource異常的另一個原因是位圖的尺寸有誤。 VCL單元中的CopyBitmap函數Graphics調用GDICheck,它始終引發一個EOutOfResource異常,但也會調用GetLastError以提供更合適的錯誤消息。

根據TPNGObject.Assign的工作方式,您應該在位圖上調用ReleaseHandleFreeImage,然後釋放它。

http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.Graphics.TBitmap.ReleaseHandle

http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.Graphics.TBitmap.FreeImage

編輯:

調用ReleaseHandle可能使事情變得更糟,因爲它會導致句柄泄漏時,沒有人會位圖處理的責任。

調用FreeImage通常不是必需的,但只在類似情況下幫助我一次。

+0

你爲什麼這麼說?我在Q. –

+0

@DavidHeffernan的代碼中看到沒有泄漏,我有一個非常相似的情況。當你不斷創建並銷燬一個位圖時,它會導致EOutOfResources。在我的情況下,我將位圖添加到TImageList。 –

+0

我不懷疑你看過類似的問題。這只是提出的解決方案看起來不像解決方案。如果它真的是一個解決方案,也許你可以解釋爲什麼Q中的代碼泄漏位圖句柄。就目前來看,這看起來像試驗和錯誤編程。 –