脱屏位图(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

Delphi GDI对象之脱屏位图(Offscreen Bitmaps)的更多相关文章

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

    http://www.cnblogs.com/pchmonster/archive/2012/07/09/2583613.html 脱屏位图(Offscreen Bitmaps) 脱屏位图,也叫内存位 ...

  2. Delphi GDI对象之绘制位图

    http://www.cnblogs.com/pchmonster/archive/2012/07/06/2579334.html 绘制位图(Drawing Bitmaps) 绘制位图听起来似乎很难, ...

  3. Delphi GDI对象之绘制文本

    转载:http://www.cnblogs.com/pchmonster/archive/2012/07/06/2579185.html 基本绘图操作(Basic Drawing Operations ...

  4. Delphi GDI对象之剪切区域

    原文链接: http://www.cnblogs.com/pchmonster/archive/2012/07/05/2577627.html 剪切区域(Clipping Regions) Regio ...

  5. 【笨嘴拙舌WINDOWS】GDI对象之位图

    GDI对象在windows中可以描述成为一次绘画操作时可使用的抽象工具.包括(画笔.画刷.字体.区域.调色板.位图等) GDI对象里的对象概念和在编程领域中面向对象编程的对象概念是不一样的! GDI对 ...

  6. Delphi GDI+ Library

    GDI+ LibraryThis library enables GDI+ functionality for Delphi 2009 and later. It differs from other ...

  7. GDI 对象的释放与内存泄漏的问题研究

    最近写了一个GDI 绘图的程序,过程中遇到一个奇怪的问题,就是 定时器定时一会GDI绘的图就消失了..后来经过分析,原来是 GDI对象数量过多 ,即GDI对象超过10000个 导致内存泄漏的问题.找到 ...

  8. 查GDI对象泄露的利器:GDIView

    查GDI对象泄露的利器:GDIView可以很详细的查到进程的GDI对象的总个数,详细的GDI对象的个数,以及其增减数量.其GDI对象类型也可以很详细的得知,以及其内存地址,句柄.实在是好使! 下载地址 ...

  9. 每添加一张图片后,GDI对象 + 3 原因: ImageList_AddIcon(hIcon) 后没调用 DestroyIcon(hIcon)

    今天无意间在[任务管理器]中发现,每添加1张图片后,应用程序的 GDI对象 + 3,添加图片后,再把所有图片删除, GDI对象数量没减少! 排查原因,发现: GDI对象 + 3 的代码是: int o ...

随机推荐

  1. Python Class (一)

    继承 class Character(object): def __init__(self, name): self.health = 100 self.name = name def printNa ...

  2. Linux直接在通过终端打开图片文件

    为了提高效率,减少使用鼠标,有时候想直接通过终端的命令打开一个图片进行查看.可以使用的命令有: eog filename display filename 再使用Alt+F4就可以关闭窗口,尽量达到手 ...

  3. 【JavaWeb项目】一个众筹网站的开发(八)后台页面详细设置

    一.user.jsp改造 删除引入菜单 抽取导航栏 nav-bar.jsp,删除引入导航栏 删除引入main.jsp的到好烂 数据库里添加url 报错,url不对 没有/ url正确 action=& ...

  4. noip2015 提高组 day1t1 神奇的幻方

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  5. 在ag-grid表格上实现类似Excel中的按下enter键自动跳转到下一行对应的输入框功能,Angular4开发

    最近的项目使用ag-grid在Angular中处理表格,收到个需求是要能够同时修改大量的数据,按下Enter键的时候,光标得自动跳到下一行的对应列上. 方法一:用ag-grid自带的 enterMov ...

  6. 工具类--Excel 导出poi

    实现功能 --批量导出excel 文件,配置一个sheet多少条数据,根据查询数据量的多少确定生成几个sheet页. pom 文件导入ExcelUtils工具包,依赖于poi包. <!-- ht ...

  7. 杂项-WebService:WebService

    ylbtech-杂项-WebService:WebService Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个 ...

  8. CentOS6.8搭建LNMP环境

    selinux可能会致使编译安装失败,我们先禁用它.永久禁用,需要重启生效 sed -i ‘s/SELINUX=enforcing/SELINUX=disabled/g’ /etc/selinux/c ...

  9. node 创建静态web服务器(上)

    声明:本文仅用来做学习记录. 本文将使用node创建一个简单的静态web服务器. 准备工作: 首先,准备好一个类似图片中这样的页面 第一步: 创建 http 服务: const http = requ ...

  10. 拯救 Out Of Memory,8个案例带你飞!

    来自:唐尤华 https://bloggceasy.files.wordpress.com/2015/05/outofmemoryerror2.pdf 1. Java 堆空间 发生频率:5颗星 造成原 ...