Delphi上的大位图

7

我想使用代码创建大位图

  LargeBmp := TBitmap.Create;
  try
    LargeBmp.Width := 1000; // fine 
    LargeBmp.Height := 15000; // XP - EOutOfResources, Not enough memory, Win 7 - works fine
    ...
  finally
    FreeAndNil(LargeBmp);
  end;

这段代码在 Windows XP 上会引发一个带有消息“内存不足”的 EOutOfResources 异常,但在 Windows 7 上可以正常工作。

问题出在哪里?为什么会出现“内存不足”?只有60 MB 的内存。


1
我猜你的意思是 LargeBmp.Height := 15000;?如果我将代码更改为这样,在 Delphi XE2 上的 Win 7/64 上可以正常工作。 - Gerry Coll
@GerryColl - 在XP下也适用于Delphi 6 - Keith Miller
3个回答

6

正如之前所讨论的,如果您不设置像素格式,Windows将把它视为设备相关位图。当您设置像素格式时,您创建了一个DIB(独立于显示设备即图形卡的设备无关位图)。

我也遇到了这个问题,并想指出pf24bit并不是唯一的选项。在Graphics单元中,您还有:

TPixelFormat = (pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom);

在我正在处理的一个项目中,我发现8位选项最适合我的需求,因为我有一个非常大的位图(高分辨率),但色彩有限(我从一些简单的代码创建整个位图)。

因此,请尝试使用除了pf24bit之外的其他选项,找到最适合您生产环境的选项。使用pf8bit选项,我节省了相当多的内部存储器。


6

像这样设置像素格式:

LargeBmp.PixelFormat := pf24Bit;

我曾多次遇到同样的问题,而这种方法总是解决了它。


2
正如Darthman所指出的那样,这将把您的位图从有限的GDI内存重新定位到您应用程序的用户内存中,最高可达2 GB。 - Warren P

5
默认情况下,创建的位图储存在某些缓冲区中。该缓冲区的大小取决于视频驱动程序、操作系统以及其他因素。这个缓冲区可能非常小(约为20-25MB),如果你尝试创建更多,则会失败。
为了避免这种情况,建议使用DIB替代TBitmap,或将Pixelformat更改为pf24bit。这将告诉系统在用户内存中创建位图,而不是GDI缓冲区。
现在,您可能会问为什么在Windows 7中没有失败?好吧,可能是因为没有GDI,而是使用了GDI+和Direct2D。也可能是其他驱动程序版本,我不知道。

默认情况下,PixelFormatpfDevice,这意味着位图被存储为设备相关的位图。您可以在此处阅读有关它的更多信息:http://msdn.microsoft.com/en-us/library/windows/desktop/dd183561(v=vs.85).aspx - Darthman
可能是因为没有GDI,但有GDI+,你的意思是什么?GDI+只是一个DLL,在GDI之上工作,可以与应用程序一起分发,并且是在WinXP时期创建的。但现在它已经过时了,像Direct 2D这样的视频卡加速API被视为“正确的方法”。那么Win7为什么缺少GDI呢? - Arioch 'The

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接