http://www.cnblogs.com/pchmonster/archive/2012/07/06/2579334.html

绘制位图(Drawing Bitmaps)

绘制位图听起来似乎很难,然而如几次所见到的那样,绘制位图非常容易。TCanvas类具有几种方法绘制位图,最常用的方法是Draw方法,这种方法只是在画布上指定位置绘制位图。用户已经见过几个这样的例子。下面是简短的例子。

1
2
3
4
5
6
7
8
9
procedure TForm1.btn1Click(Sender: TObject);
var
  Bitmap: TBitmap;
begin
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromFile('type.bmp');
  Canvas.Draw(0, 0, Bitmap);
  Bitmap.Free;
end;

这段代码创建了一个TBitmap对象,装载一副BMP位图,并在窗口的最上角显示。

若显示位图不需修改时,可使用Draw方法。


StretchDraw方法用于改变位图的大小。用户在所需绘制的位图和图像位置确定确定一个矩形框。如果所用矩形框大于位图的原始大小,则放大位图;如果矩形框小于位图的原始大小,则缩小位图,这里是一个例子:

1
2
3
4
5
6
7
8
9
10
11
procedure TForm1.btn2Click(Sender: TObject);
var
  Bitmap: TBitmap;
  R: TRect;
begin
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromFile('type.bmp');
  R := Rect(0, 0, 150, 150);  { 将原始300x300的位图缩放为150x150}
  Canvas.StretchDraw(R, Bitmap);
  Bitmap.Free;
end;

以上代码将位图缩放为150x150像素大小,效果如下:

Note

StretchDraw没法保持位图的原始长宽比率。这完全由用户确认位图保持它的原始长宽比率。


另一个位图绘制方法是CopyRect。这种方法要求同时指定源矩形框和目标矩形框。这就可以将位图分成片段显示,下面的例子就是:

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
procedure TForm1.btn3Click(Sender: TObject);
var
  Bitmap: TBitmap;
  Src: TRect;
  Dst: TRect;
  I, X, Y: Integer;
  Strips: Integer;
  Stripsize: Integer;
  OldPal: HPALETTE;
begin
  ClearCanvas;
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromFile('type.bmp');
  Strips := 6; { 分成六份}
  Stripsize := Bitmap.Height div Strips;
  OldPal := SelectPalette(Canvas.Handle, Bitmap.Palette, True);
  for I := 0 to Pred(Strips) do
  begin
    Src := Rect(0, i * Stripsize, Bitmap.Width, (i * Stripsize) + Stripsize);
    X := Random(Width - Bitmap.Width);
    Y := Random(Height - Stripsize);
    Dst := Rect(X, Y, X + Bitmap.Width, Y + Stripsize);
    Canvas.CopyRect(Dst, Bitmap.Canvas, Src);
  end;
  SelectPalette(Canvas.Handle, OldPal, True);
  Bitmap.Free;
end;

这段代码装载位图,将它分割成片段,然后在窗体任意位置显示这些片段。下图就是这段代码的显示结果。

拷贝位图片段咋一看似乎没有多大意义,然而普通的图形程序设计方法就是创建由一些小的图像构成的大图,并只是将用户需要的图形拷贝到屏幕上。在这种情况下,CopyRect方法就可以使用。

Note

上面的代码中利用SelectPalette函数设置窗体调色板为位图的调色板属性。由于某些奇特的原因,TCanvas类没有调色板属性,因此必须采用API设置窗体调色板。如果没有设置调色板,那么当位图片段显示在窗体上时颜色时错乱的,CopyRect方法是用不同原理在画布上显示位图,因此当使用这种方法时,采用这种特别的步骤是很必要的。

在Windows2000下256色显示设置下,使用与不使用SelectPalette函数的效果对比图:

还有一种位图绘制方法需要提及,BrushCopy方法要求用户指定源矩形框、目标矩形框、图像和透明色,BrushCopy联机帮助中指出,使用ImageList组件而不要用这种方法,但是有时BrushCopy使用的很好,而且使用起来比ImageList组件要容易。使用具有透明背景的位图时记得使用BrushCopy方法。

Delphi syntax:

1
procedure BrushCopy(const Dest: TRect; Bitmap: TBitmap; const Source: TRect; Color: TColor);

下面的例子,展示了CopyRect和BrushCopy显示同一位图的效果,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TForm1.btn4Click(Sender: TObject);
var
  Bitmap: TBitmap;
  MyRect, MyOther: TRect;
begin
  MyRect := Rect(10, 10, 310, 165);
  MyOther := Rect(10, 170, 310, 320);
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromFile('pchmonster.bmp');
  Canvas.BrushCopy(MyRect, Bitmap, Rect(0, 0, 300, 150), clwhite);
  Canvas.CopyRect(MyOther, Bitmap.Canvas, Rect(0, 0, 300, 150));
  Bitmap.Free;
end;

运行后,BrushCopy的透明背景位图效果明显。如下图:


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

Delphi GDI对象之绘制位图的更多相关文章

  1. Delphi GDI对象之绘制文本

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

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

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

  3. Delphi GDI对象之脱屏位图(Offscreen Bitmaps)

    脱屏位图(Offscreen Bitmaps) 脱屏位图,也叫内存位图,普遍用于Windows程序设计中.它在内存中制作图像,然后利用Draw方法在屏幕上显示出来.当用户想更快的在屏幕上绘制图像时,脱 ...

  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(一)

    Delphi 7下IGDIPlus库的使用 IGDI+是一个免费开源封装微软GDI+功能的Delphi库,该库使得可以用Delphi语言代码快速简短的实现复杂GDI+应用程序. 官方网站:http:/ ...

  7. DX笔记之五------游戏画面绘图之绘制位图

    本系列文章由zhmxy555编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7335103 共四步 步骤一:加载位图 步骤二:建立与 ...

  8. VS2010/MFC编程入门之五十(图形图像:GDI对象之画笔CPen)

    上一节中鸡啄米讲了CDC类及其屏幕绘图函数,本节的主要内容是GDI对象之画笔CPen. GDI对象 在MFC中,CGdiObject类是GDI对象的基类,通过查阅MSDN我们可以看到,CGdiObje ...

  9. 关于SelectObject之后是否要恢复之前的GDI对象

    以下列代码为例 { // 创建内存DC CDC mMemDc; mMemDc.CreateCompatibleDC( &dc ); // 创建兼容位图 CBitmap bmpMemBmp; b ...

随机推荐

  1. paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之fsm summary

    主要是1.不要用1段式写FSM 2.不要用状态编码写one-hot FSM ,要用索引编码写one-hot FSM.

  2. 【python学习】新手基础程序练习(一)

    首先得先编一下程序员必须编的程序——Hello World……(这应该是程序员情结...) #coding=utf-8 #Version:python3.7.0 #Tools:Pycharm 2017 ...

  3. Django之用户认证

    用户认证组件简介 功能:用session记录登录验证状态 前提:必须使用django自带的auth_user表.那这里有的同学就会有疑问了,自己不能创建自己的用户表吗? 当然可以,用户认证组件虽然只针 ...

  4. 水题:51Nod 1163-最高的奖励

    最高的奖励 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 Description 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励.在结束时间之前完成该任 ...

  5. selenium2截图ScreenShot的使用

    截图是做测试的基本技能,在有BUG的地方,截个图,保留失败的证据,也方便去重现BUG.所以,在自动化的过程中,也要能截图,也要能在我们想要截取的地方去截图,且能在错误产生时,自动的截图. 示例: 脚本 ...

  6. 遍历Request.QueryString

    Request.QueryString 返回的是 NameValueCollection, 而NameValueCollection实现了IEnumerable的GetEnumerator方法,只是G ...

  7. oracle中的dual表

    dual表是和Oracle数据字典一起创建的.它实际上只包含dummy这一个column,并且只有一条记录,这条记录的值是X. X dual表的owner是SYS,但所有用户都可以访问它.Althou ...

  8. RabbitMQ与PHP(一)

    RabbitMQ与PHP(一) 项目中使用RabbitMQ作为队列处理用户消息通知,消息由前端PHP代码产生,处理消息使用Python,这就导致代码一致性问题,调整消息定义时需要PHP和Python都 ...

  9. 【bzoj2338】[HNOI2011]数矩形 计算几何

    题目描述 题解 计算几何 由于对角线平分且相等的四边形是矩形,因此我们可以把每条对角线存起来,按照对角线长度和中点位置为关键字排序,这样对于每个相同长度和中点的对角线就排到了一起. 于是对于每段可能形 ...

  10. 【Luogu】P2657windy数(数位DP)

    题目链接 正式迈入了数位DP的大门…… 心情激动 (看我立个flag,我如果专攻数位DP的话,到wc之前就会有秒数位DP蓝题的能力) 数位DP讲解链接 讲的非常详细,良心博客.比我写的博客加在一起还要 ...