【发布时间】:2011-10-30 14:50:56
【问题描述】:
我在尝试设置 BMP.Height 或 BMP.Width 时尝试使用 BMP 文件时收到“EOutofresources - 存储空间不足”。在这些指令之后,堆栈跟踪是(按此顺序): ntdll.dll.RtlLeaveCriticalSection、kernel32.dll.FileTimeToDosDateTime、GDI32.dll.GdiReleaseDC、GDI32.dll.PatBlt、kernel32.dll.ReadFile 或类似这样:
|7E429130|user32.dll GetParent
|7C90FF2D|ntdll.dll RtlGetNtGlobalFlags
|77F15A00|GDI32.dll GdiReleaseDC
|7C83069E|kernel32.dll FileTimeToDosDateTime
|7C9010E0|ntdll.dll RtlLeaveCriticalSection
| |my function (where I set BMP.Height or BMP.Width)
有一刻我确信它必须与内存碎片有关 - 系统有足够的可用内存来处理我的图像但是内存碎片所以没有足够大的块来容纳我的图像。但后来我看到它在 Windows 启动后 11 秒发生一次。我的程序循环通过我只处理一次图像的循环!因此,这与 RAM 碎片无关。
出现此错误时的另一种情况(但仍与绘图有关)如下:
|77F16A7E|GDI32.dll IntersectClipRect
|77F16FE5|GDI32.dll BitBlt
|7E429011|user32.dll OffsetRect
|7E42A97D|user32.dll CallWindowProcA
|7E42A993|user32.dll CallWindowProcA
|7C9010E0|ntdll.dll RtlLeaveCriticalSection
|7E4196C2|user32.dll DispatchMessageA
|7E4196B8|user32.dll DispatchMessageA
|0058A2E1|UTest.exe UTest.dpr
|7C90DCB8|ntdll.dll ZwSetInformationThread
我认为在 BMP.Height 之后的堆栈跟踪中总是有一个“RtlLeaveCriticalSection”调用。
this 帖子通过编辑 Windows 注册表项指向可能的解决方案。但是,该帖子说它仅适用于 Win XP。虽然我的错误也出现在 Win 7 上。
我看到许多类似的帖子(其中一些与将文件保存到磁盘密切相关),但直到没有人回来报告他修复了错误。
更新:
根据您的要求,这是出现错误的代码:
procedure TMyBitmap.SetLargeSize(iWidth, iHeight: Integer);
CONST ctBytesPerPixel= 3;
begin
{ Protect agains huge/empty images }
if iWidth< 1 then iWidth:= 1 else
if iWidth> 32768 then iWidth:= 32768;
if iHeight< 1 then iHeight:= 1 else
if iHeight> 32768 then iHeight:= 32768;
{ Set image type }
if iWidth * iHeight * ctBytesPerPixel > 9000000 {~9MB}
then HandleType:= bmDIB { Pros and cons: -no hardware acceleration, +supports larger images }
else HandleType:= bmDDB;
{ Total size is higher than 1GB? }
if (iWidth* iHeight* ctBytesPerPixel) > 1*GB then
begin
Width := 8000; { Set a smaller size }
Height := 8000; { And rise an error }
RAISE Exception.Create('Image is too large.');
end;
{ Set size }
Width := iWidth; <----------------- HERE
Height:= iHeight;
end;
【问题讨论】:
-
请显示源代码...听起来更像是资源泄漏(即句柄泄漏)而不是内存问题...
-
位图有多大?
-
位图可以是任意大小。通常它们应该是普通的数码相机图片(4-16 Mpixels)。
-
更新:这家伙说他有一个解决方案,将格式设置为 pf24bit:stackoverflow.com/questions/1473165/…
-
汇集您的图像,不要不断创建/销毁。
标签: delphi