当我尝试设置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)
此刻我确信它必须对内存碎片做一些事情 - 系统有足够的免费ram来处理我的图像但内存是碎片的,所以没有足够大的块来保存我的图像。但后来我看到它在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;
答案 0 :(得分:4)
从我的实验中,最大位图大小取决于:
因此,当您开始使用大量数据(超过屏幕上的位图分辨率)时,您无法确定位图分配是否成功。
以下是一些可能的解决方案(我已经使用了其中一些):
没有完美的解决方案(我的偏好是使用较小的图片,因为它具有易于多线程处理的优点,因此可以通过新CPU加速很多),并且要注意资源分配可能在您的全新64位Windows 7 PC上工作,但在客户的32位XP计算机上失败。