【问题标题】:Delphi fast large bitmap creation (without clearing)Delphi 快速大位图创建(无需清除)
【发布时间】:2010-03-23 14:04:47
【问题描述】:

当使用 TBitmap 包装器从单元 Graphics 中获取 GDI 位图时,我注意到在使用 SetSize(w, h) 设置位图时,它总是会清除位图(使用 PatBlt 调用)。当我稍后复制位时(参见下面的例程),似乎 ScanLine 是最快的可能性,而不是 SetDIBits。

function ToBitmap: TBitmap;
var
    i, N, x: Integer;
    S, D:    PAnsiChar;
begin
  Result := TBitmap.Create();
  Result.PixelFormat := pf32bit;
  Result.SetSize( width, height );
  S := Src;
  D := Result.ScanLine[ 0 ];
  x := Integer( Result.ScanLine[ 1 ] ) - Integer( D );
  N := width * sizeof( longword );
  for i := 0 to height - 1 do begin
    Move( S^, D^, N );
    Inc( S, N );
    Inc( D, x );
  end;
end;

我需要处理的位图非常大(150MB 的 RGB 内存)。使用这些图像需要 150 毫秒来简单地创建一个空位图,并需要 140 毫秒来覆盖它的内容。

有没有一种方法可以用正确的大小初始化一个 TBitmap,而不用初始化像素本身并使像素的内存未初始化(例如脏)?或者有没有另一种方法来做这样的事情。我知道我们可以在原地处理像素,但这仍然会留下 150 毫秒的不必要的像素初始化。

【问题讨论】:

    标签: delphi optimization bitmap


    【解决方案1】:

    在这里您可以做的事情并不多 - 处理巨大的位图很慢...但您可以尝试以下操作:

    1. 在调用 SetSize() 后设置 PixelFormat - 这不会避免像素初始化,但可能会使其更快。

    2. 我能想到的最快方法是使用 Win32 API 函数(thisthis)创建一个 DIB,并将该 DIB 的 HBITMAP 句柄分配给您的 TBitmap 对象的句柄。

    3. 使用内存映射文件(再次需要调用 API,或者有一些第三方库可以为您做到这一点)。

    【讨论】:

    • 谢谢 Alex,目前我尝试使用内存 blob 而不是真正的位图。然而,当我需要在屏幕上显示位图时,我需要一个位图(并会导致时间损失)。 1 明显更慢。 2 需要一些时间来调整,但直到现在还没有给我正确的结果。 3. 不可能,因为图像不是来自文件,而是仅在内存中。
    • 在这种情况下,您可以尝试使用 CreateBitmapIndirect API 函数 (msdn.microsoft.com/en-us/library/dd183486%28VS.85%29.aspx) 创建新的位图。我认为它会使用您在内存中的现有数据并且不会重新分配它们。
    • 使用 CreateBitmap 或 CreateBitmapIndirect 时,我减少了大约 40 毫秒(从 150+140 到 250 毫秒)!
    • 40ms 可能是调用 PatBlt() 所花费的时间。
    • @Alex: noppes; patblt 用了 150 毫秒,复制数据用了 140 毫秒,调用 createbitmap 用了 250 毫秒(它在后台复制数据,因为当你释放工作内存时它会继续工作)。所以它速度较慢,但​​因为您避免了一种低效率,所以它速度更快,是迄今为止最好的选择。
    【解决方案2】:

    这就是我在类似问题上所做的:

    1. Graphics.pas 单元的内容复制到一个名为 MyGraphics.pas 的新单元中
    2. 在新的 MyGraphics.pas 中查找函数 CopyBitmap 的实现并注释掉以下行:PatBlt(NewImageDC, 0, 0, bmWidth , bmHeight, 白度);
    3. 在您的 Delphi 项目中将 Graphics 的使用替换为 MyGraphics

    就是这样,创建更快的空位图...

    【讨论】:

      猜你喜欢
      • 2013-08-07
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      相关资源
      最近更新 更多