2010-03-23 48 views
4

当使用TBitmap包装从单元的图形,我注意到一个GDI的位图,它会永远清除出位图(使用PatBlt调用)设立时的setSize位图(W, H )。当我在位复制以后(见下面的例程)似乎扫描线是最快的可能性,而不是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不初始化像素本身并留下像素的内存未初始化的方式(如脏的)?或者有另一种方式来做这样的事情。我知道我们可以在像素上工作,但是这仍然会留下像素的150ms不一致的初始化。

回答

4

这里没有很多事情可以做,在这里 - 巨大的位图的工作是慢......但你可以尝试以下操作:调用的setSize()后

  1. 集的PixelFormat - 这将无法避免的初始化像素,但可能会更快。

  2. 我能想到的最快的方法是使用Win32 API函数(thisthis)创建DIB,而DIB的分配HBITMAP处理您TBitmap对象的句柄。

  3. 使用内存映射文件(再次需要调用API或替代地也有一些能为你做的第三方库)。

+0

谢谢亚历克斯,在现阶段,我尝试使用内存斑点,而不是一个真正的位图都没有。然而,我需要在屏幕上显示位图的那一刻,我需要一个位图(并导致时间损失)。 1基本上较慢。 2需要一些时间调整,但直到现在还没有给我正确的结果。 3.是不可能的,因为图像不是来自文件,而是完全在内存中。 – 2010-03-23 14:49:46

+0

在这种情况下,你可以尝试创建一个使用CreateBitmapIndirect API函数(http://msdn.microsoft.com/en-us/library/dd183486%28VS新的位图。85%29.aspx)。我认为它会在内存中使用你现有的数据,不会重新分配它们。 – 2010-03-23 15:03:38

+0

当使用CreateBitmap或CreateBitmapIndirect时,我刮掉大约40ms(从150 + 140到250ms)! – 2010-03-23 15:38:56

0

这就是我做了一个类似的问题:

  1. 复制Graphics.pas的内容单元到一个新的单位,称为MyGraphics.pas
  2. 在新MyGraphics.pas查找功能的实现CopyBitmap与注释掉该行:PatBlt(NewImageDC,0,0,bmWidth,bmHeight,白度);
  3. 替换使用图形MyGraphics无处不在您的Delphi项目。

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