Delphi GDI對象之脫屏位圖(Offscreen Bitmaps)


脫屏位圖(Offscreen Bitmaps)

脫屏位圖,也叫內存位圖,普遍用於Windows程序設計中。它在內存中制作圖像,然后利用Draw方法在屏幕上顯示出來。當用戶想更快的在屏幕上繪制圖像時,脫屏位圖有助於避免閃爍。脫屏位圖也適合於復雜制圖程序。用戶可以將圖像預存起來,需要時顯示出來。脫屏位圖用於動畫,最流行的動畫制作方法是Microsoft的DirectX SDK。

脫屏位圖的原則是三個簡單的步驟:

  1. 建立內存位圖(Create a memory bitmap)
  2. 繪制內存位圖(Draw on the memory bitmap)
  3. 拷貝內存位圖於屏幕(Copy the memory bitmap to the screen)

創建內存位圖(Creating a Memory Bitmap)

創建內存位圖很容易。事實上,前面的講解中已經創建過好幾次了。每次創建TBitmap對象時就是在創建內存位圖,其中一些是將文件載入內存位圖中,還有一些是創建內存位圖,設置其大小,然后繪制內存位圖,例如:

procedure TForm1.btn1Click(Sender: TObject);
var
  Bitmap: TBitmap;
  I, X, Y, W, H: Integer;
  Red, Green, Blue: Integer;
begin
  Bitmap := TBitmap.Create;
  Bitmap.Width := 500;
  Bitmap.Height := 500;
  for I := 0 to 19 do
  begin
    X := Random(400);
    Y := Random(400);
    W := Random(100) + 50;
    H := Random(100) + 50;
    Red := Random(255);
    Green := Random(255);
    Blue := Random(255);
    Bitmap.Canvas.Brush.Color := RGB(Red, Green, Blue);
    Bitmap.Canvas.Rectangle(X, Y, W, H);
  end;
  Canvas.Draw(0, 0, Bitmap);
  Bitmap.Free;
end;

每次點擊按鈕,隨意一串矩形框畫於屏幕上。這段代碼簡單地繪制內存位圖,然后將位圖拷貝到窗體畫面上。

image

如果使用桌面256色設置,最終運行的結果的顏色將不確定。

Note

當創建內存位圖時,位圖將具有與當前顯示設置相同的顏色深度。換句話說,若有256種顏色的顯示設置,內存位圖也是256色的位圖,如果顯示設置為24位或32位,則內存位圖將包含32K、64K或16M種顏色。

 


保存內存位圖(Saving a Memory Bitmap)

將內存位圖保存起來極其容易。它所需要的做的就是一下代碼:

Bitmap.SaveToFile('test.bmp'); { 保存內存位圖}

是的,這樣就可以。事實上可以很容易地創建自己的屏幕捕捉程序。所要做的只是將桌面的適當部分拷貝到內存位圖中,並存儲到文件中。如下代碼:

procedure TForm1.btn2Click(Sender: TObject);
var
  DtCanvas: TCanvas;
  Bitmap: TBitmap;
  NumColor: Integer;
  LogPal: PLogPalette;
  Src, Dst: TRect;
begin
  { Create a TCanvas object for the desktop DC.}
  DtCanvas := TCanvas.Create;
  DtCanvas.Handle := GetDC(0);

  { Create a new TBitmap object and set its}
  { size to the size of the form.}
  Bitmap := TBitmap.Create;
  Bitmap.Width := Width;
  Bitmap.Height := Height;

  { Create a palette from the form's Canvas}
  { and assign that palette to the Bitmap's}
  { Palette property.}
  NumColor := GetDeviceCaps(Canvas.Handle, SIZEPALETTE);
  { 返回調色板的顏色數}
  GetMem(LogPal, SizeOf(TLogPalette) + (NUMCOLORS - 1) * SizeOf(TPaletteEntry));
  LogPal.palVersion := $300;
  LogPal.palNumEntries := NumColor;
  GetSystemPaletteEntries(Canvas.Handle, 0, NumColor, LogPal.palPalEntry);
  Bitmap.Palette := CreatePalette(LogPal^);
  FreeMem(LogPal);

  { Copy a section of the screen from the
    desktop canvas to the Bitmap }
  Src := BoundsRect;
  Dst := Rect(0, 0, Width, Height);
  Bitmap.Canvas.CopyRect(Dst, DtCanvas, Src);

  { Save it to disk}
  Bitmap.SaveToFile('form.bmp');
  { Clean up and go home}
  Bitmap.Free;
  DtCanvas.Free;
end;

運行后,將截取本程序界面並保存到form.bmp文件中,顯示圖片如下:

form


內存位圖程序實例(Sample Memory Bitmap Program)

下面的清單中的程序,它說明內存位圖的應用。當點擊兩個按鈕中的某一個時,文本沿着屏幕水平滾動。

第一個按鈕的實現,不使用內存位圖(直接寫於窗體畫面上)。

第二個按鈕使用內存位圖來實現文本屏幕水平滾動。

第三個按鈕停止滾動。

部分代碼如下(詳細代碼請下載本講示例代碼):

{ 直接畫到畫布上}
procedure TForm1.btn3Click(Sender: TObject);
var
  I: Integer;
begin
  Canvas.Font.Name := 'Arial Bold';
  Canvas.Font.Size := 20;
  Canvas.Brush.Color := clSilver;
  Done := False;
  while not Done do
  begin
    for I := -canvas.TextWidth(DisplayText) to pred(Width) do
    begin
      Sleep(1);
      Application.ProcessMessages;
      if Done then
        Break;
      Canvas.Font.Color := clGray;
      Canvas.Brush.Style := bsClear;

      Canvas.TextOut(i + 2, 12, DisplayText);

      Canvas.Font.Color := clBlack;
      Canvas.Brush.Style := bsClear;
      Canvas.TextOut(i, 10, DisplayText);
      Canvas.Font.Color := clSilver;
      Canvas.TextOut(i + 2, 12, DisplayText);
      Canvas.TextOut(i, 10, DisplayText);
    end;
  end;
end;

{ 通過脫屏位圖}
procedure TForm1.btn5Click(Sender: TObject);
begin
  Done := True;
end;

procedure TForm1.btn4Click(Sender: TObject);
var
  Bitmap: TBitmap;
  I: Integer;
begin
  Bitmap := TBitmap.Create;
  Bitmap.Width := Width;
  Bitmap.Height := 40;
  Bitmap.Canvas.Font.Name := 'Arial Bold';
  Bitmap.Canvas.Font.Size := 20;
  Bitmap.Canvas.Brush.Color := clSilver;
  Bitmap.Canvas.FillRect(Rect(0, 0, Width, 40));
  Done := False;
  while not Done do
  begin
    for I := -Bitmap.Canvas.TextWidth(DisplayText) to Pred(Width) do
    begin
      Application.ProcessMessages;
      if (Done) then
        Break;
      Sleep(1);
      Bitmap.Canvas.Font.Color := clGray;
      Bitmap.Canvas.Brush.Style := bsClear;
      Bitmap.Canvas.TextOut(2, 12, DisplayText);
      Bitmap.Canvas.Font.Color := clBlack;
      Bitmap.Canvas.Brush.Style := bsClear;
      Bitmap.Canvas.TextOut(0, 10, DisplayText);
      Canvas.Draw(i, 0, Bitmap);
    end;
  end;
  Bitmap.Free;
end;

 

兩種不同的畫圖方式,顯示的效果也不同,其中通過脫屏位圖繪制的滾動字幕是最平滑的。如下圖:

image

 

以上代碼均在Delphi7中測試通過,示例代碼下載:GDI之脫屏位圖.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM