Delphi GDI对象之脱屏位图(Offscreen Bitmaps),也叫内存位图

http://www.cnblogs.com/pchmonster/archive/2012/07/09/2583613.html

 

脱屏位图(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对象时就是在创建内存位图,其中一些是将文件载入内存位图中,还有一些是创建内存位图,设置其大小,然后绘制内存位图,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;

每次点击按钮,随意一串矩形框画于屏幕上。这段代码简单地绘制内存位图,然后将位图拷贝到窗体画面上。

Delphi GDI对象之脱屏位图(Offscreen Bitmaps),也叫内存位图_第1张图片

如果使用桌面256色设置,最终运行的结果的颜色将不确定。

Note

当创建内存位图时,位图将具有与当前显示设置相同的颜色深度。换句话说,若有256种颜色的显示设置,内存位图也是256色的位图,如果显示设置为24位或32位,则内存位图将包含32K、64K或16M种颜色。

 

保存内存位图(Saving a Memory Bitmap)

将内存位图保存起来极其容易。它所需要的做的就是一下代码:

1
Bitmap.SaveToFile('test.bmp'); { 保存内存位图}

是的,这样就可以。事实上可以很容易地创建自己的屏幕捕捉程序。所要做的只是将桌面的适当部分拷贝到内存位图中,并存储到文件中。如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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文件中,显示图片如下:

Delphi GDI对象之脱屏位图(Offscreen Bitmaps),也叫内存位图_第2张图片

 

 

内存位图程序实例(Sample Memory Bitmap Program)

下面的清单中的程序,它说明内存位图的应用。当点击两个按钮中的某一个时,文本沿着屏幕水平滚动。

第一个按钮的实现,不使用内存位图(直接写于窗体画面上)。

第二个按钮使用内存位图来实现文本屏幕水平滚动。

第三个按钮停止滚动。

部分代码如下(详细代码请下载本讲示例代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{ 直接画到画布上}
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;

 

两种不同的画图方式,显示的效果也不同,其中通过脱屏位图绘制的滚动字幕是最平滑的。如下图:

Delphi GDI对象之脱屏位图(Offscreen Bitmaps),也叫内存位图_第3张图片

 

以上代码均在Delphi7中测试通过,示例代码下载:GDI之脱屏位图.rar

你可能感兴趣的:(Delphi GDI对象之脱屏位图(Offscreen Bitmaps),也叫内存位图)