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

  • 相关阅读:
    修复upstream sent too big header while reading response header from upstream
    Ubuntu下安装可视化SVN客户端Rabbitvcs
    nginx优化 突破十万并发
    Nginx: 24: Too Many Open Files 错误和解决方案
    TCP与UDP协议的Socket通信
    数据传输之流的理解
    单链表算法题及其解析
    一个JS的面试题及其解析
    asp.net中用MARQUEE实现流动文字的公告栏
    利用JavaScript关闭当前窗口
  • 原文地址:https://www.cnblogs.com/blogpro/p/11426610.html
Copyright © 2011-2022 走看看