Delphi快速创建大型位图(无需清除)

时间:2010-03-23 14:04:47

标签: delphi optimization bitmap

当使用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内存)。使用这些iomages,只需创建一个空位图需要150ms,再过140ms来覆盖它的内容。

有没有办法用正确的大小初始化TBitmap没有初始化像素本身并且像素的内存未初始化(例如脏)?还是有另一种方法来做这样的事情。我知道我们可以处理像素,但这仍然留下了150毫秒的像素初始化。

3 个答案:

答案 0 :(得分:4)

这里你可以做的事情并不多 - 使用巨大的位图很慢......但你可以尝试以下方法:

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

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

  3. 使用内存映射文件(再次需要调用API,或者有一些第三方库可以为您执行此操作)。

答案 1 :(得分:0)

此链接包含一些您可能感兴趣的基准:

http://ksymeon.blogspot.com/2010/02/getdibits-vs-scanline-vs-pixels-in.html

答案 2 :(得分:0)

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

  1. Graphics.pas 单元的内容复制到名为 MyGraphics.pas
  2. 的新单元
  3. 在新的 MyGraphics.pas 中查找函数 CopyBitmap 的实现,并注释掉以下行: PatBlt(NewImageDC,0,0,bmWidth ,bmHeight,WHITENESS);
  4. 将Delphi项目中 Graphics 的用法替换为 MyGraphics
  5. 这就是它,创建更快的空位图...