脫屏位圖(Offscreen Bitmaps)
脫屏位圖,也叫內存位圖,普遍用於Windows程序設計中。它在內存中制作圖像,然后利用Draw方法在屏幕上顯示出來。當用戶想更快的在屏幕上繪制圖像時,脫屏位圖有助於避免閃爍。脫屏位圖也適合於復雜制圖程序。用戶可以將圖像預存起來,需要時顯示出來。脫屏位圖用於動畫,最流行的動畫制作方法是Microsoft的DirectX SDK。
脫屏位圖的原則是三個簡單的步驟:
- 建立內存位圖(Create a memory bitmap)
- 繪制內存位圖(Draw on the memory bitmap)
- 拷貝內存位圖於屏幕(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;
每次點擊按鈕,隨意一串矩形框畫於屏幕上。這段代碼簡單地繪制內存位圖,然后將位圖拷貝到窗體畫面上。
如果使用桌面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文件中,顯示圖片如下:
內存位圖程序實例(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;
兩種不同的畫圖方式,顯示的效果也不同,其中通過脫屏位圖繪制的滾動字幕是最平滑的。如下圖:
以上代碼均在Delphi7中測試通過,示例代碼下載:GDI之脫屏位圖.rar



