zoukankan      html  css  js  c++  java
  • Delphi GDI对象之脱屏位图(Offscreen Bitmaps)

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

    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;

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

    如果使用桌面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文件中,显示图片如下:

    内存位图程序实例(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;

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

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

  • 相关阅读:
    AJAX异步传输——以php文件传输为例
    js控制json生成菜单——自制菜单(一)
    vs2010中关于HTML控件与服务器控件分别和js函数混合使用的问题
    SQL数据库连接到服务器出错——无法连接到XXX
    PHP错误:Namespace declaration statement has to be the very first statement in the script
    【LeetCode】19. Remove Nth Node From End of List
    【LeetCode】14. Longest Common Prefix
    【LeetCode】38. Count and Say
    【LeetCode】242. Valid Anagram
    【LeetCode】387. First Unique Character in a String
  • 原文地址:https://www.cnblogs.com/blogpro/p/11426610.html
Copyright © 2011-2022 走看看