2010-03-23 43 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項目。

就是這樣,更快地創建位圖空...