生成大量位图时,位图创建会变为全黑



我正在使用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;

我在Bmp.Free之前尝试过CloseHandle(Bmp.Handle),但我遇到了一个EExternalException。

谢谢大家的帮助!


2012年12月6日更新:

感谢Arioch的回答,我尝试直接设置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;

2012年12月20日更新:

在联系FlashPlayerControl开发团队后,我发现当应用程序达到10000个GDI对象时,位图会变黑。他们为我的问题提供了有效的帮助,联系他们是有效的:)

我最终发现GDI对象泄漏来自我代码的另一个并行部分。这个主题很接近:)

当TBitmap创建的句柄被错误代码使用时,句柄可能没有正确清理。该句柄泄漏累积,并且在几次这样的泄漏之后GetDC开始失效。

EOutOfResource异常的另一个原因是位图的维度错误。VCL单元Graphics中的CopyBitmap函数调用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通常是不必要的,但在类似情况下只帮助过我一次。

最新更新