C++Builder - 6图形、图像及实例

更新时间:2024-05-09 07:55:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

ok

C++Builder图形、图像及实例

. 内容提要:本文介绍了图形的绘制和图像处理,其中详细介绍了画布(Canvas)的属性与使用 方法,利用它们,可以非常直观方便地绘制直线、曲线、矩形、椭圆等各种图形。本文还介绍了图 像处理的方法,其中包括 Image组件、TBitmap类和 TJPEGImage类的使用,而要进行快速的图像 处理,几乎都离不开 ScanLine技术。使用 ScanLine技术,能够快速取得 bitmap的每行的颜色值, 而无需使用 Canvas的 Pixels属性逐点获取像素点的颜色值。

关键字:C++Builder、图形、图像、画布

w et

引言:自 Windows诞生以来,可以通过 GDI(Graphics Device Interface)来实现图形的绘制。

然而对于初学者来说,庞大复杂的 GDI绘图系统是一个难以跨越的学习障碍。所幸的是,在

C++Builder绘图系统中,提供了一个简易可行的画布( Canvas),可以用非常直观的方式来实现

Windows下的绘图功能。C++Builder提供了 Image组件,可以很方便地装载图像,以及进行图像处 理。

正文:

1在窗体上作图

1.1知识要点

1.画布( Canvas)

在 C++Builder中,几乎所有的可视化组件(包括:Form、Image、Bitmap、PaintBox)都包含

Canvas属性。Canvas包含了许多和绘图有关的性质,如 Pen、Brush、Pixels、Font等,另外它还包

含了各种绘图的函数,如 LineTo、Rectangle、MoveTo、Polygon等。

(1)Canvas类主要属性有: Font:画布绘制文本所用的字体。

Brush:用于填充背景的画笔刷。 Pen:用来画线和描述图形轮廓的画笔。 PenPos:当前绘图位置的坐标。 Pixels:画布像素数组。 (2)Canvas类主要方法有: Arc:用当前画笔在画布上画圆弧。

Chord:绘制由直线和椭圆相交而成的一个封闭形状。 CopyRect:将图形的一部分从另一个画布复制过来。 Ellipse:在给定的区域绘制椭圆。

FillRect:用当前画刷填充指定的矩形。 FloodFill:用当前画刷填充指定的区域。

(3)LineTo类主要方法有: MoveTo:连同 LineTo绘制直线。

Polyline:绘出一系列的线,串起所传入的各个点。 Rectangle:绘制圆角矩形。 TextOut:在画布上写出字符串。

TextRect:在限定的区域写出字符串,区域之外的字符串不会被显示出来。 2.颜色常数

Polygon:绘出一系列的线,串起所传入的各个点,并从最后一点到第一点绘制一条线。

StretchDraw:在画布上给定的大小绘制图像。

在 C++Builder中提供了许多颜色的预定常数,这些预设颜色都以 cl(cl代表 color)为启始字

※ 1※

o

符命名。例如 clRed代表红色,clBlue代表蓝色,clGreen代表绿色等等。另外 C++Builder也将 Windows

的基本颜色以常数定义,如 clWindow及 clMenu分别代表 Window及 Menu(菜单)的颜色。

下面列出部分 C++Builder定义的颜色常数:

cn ok

clBlack:黑色。 clGreen:绿色。 clOlive:橄榄绿。 clNavy:海蓝色。 clPurple:紫色。 clTeal:青紫色。 clGray:灰色。 clSilver:银色。 clRed:红色。 clLime :灰绿色。

clBlue:蓝色。

clAqua:淡绿青色。 clWhite:白色。

clBackground:Window背景色。 clActiveCaption:活动视窗的标题色。 clInactiveCaption:非活动视窗的标题色。 clMenu:Menu的颜色。

clWindow:Windows的背景色。 clMenuText:Menu 文字的颜色。 clWindowText:Window内文字的颜色。 clCaptionText:标题文字的颜色。

clActiveBorder:活动视窗的边界颜色。 clHighlight:高亮度 Windows颜色。 clHightlightText:被选取文字的颜色。 clGrayText:灰色文字的颜色。 clBtnText:Button内文字的颜色。 Canvas -> Pixels [3][5]=clBlue;

以下的程序表示将画布中(3,5 )这一像素点的颜色设为蓝色: 另外,也可以利用以下的叙述来设定画笔的颜色为蓝色: Canvas->Pen->Color=RGB(0,0,255); 3. RGB函数

任何一种颜色都是由红、绿、蓝三种基本色构成的。RGB函数是 Windows系统用以表示颜色

的方式,它们用三个字节型参数变量,分别代表红色(Red)、绿色( Green)及蓝色(Blue)的强度 值(0~255之间),组合起来表示颜色。例如 RGB(255,0,0)代表红色(RGB(255,0,0)所代表的 颜色和颜色常数 clRed是相同的)。

如果 RGB函数中的三个参数相同,即红、绿、蓝的强度值一样,则其代表的颜色是黑白的。 例如 RGB(255,255,255)代表白色,RGB( 0,0,0)代表黑色。

4. Tcolor类 如:

Tcolor是表示颜色的类,其实例可以是 clRed、clBlue、clGreen等刚才介绍到的颜色常数,例 Tcolor color=clRed;

也可以使用 RGB函数来取值,例如:

※ 2※

o

(4, 34, 253); Tcolor color= RGB

5. Pen和 Brush

cn ok

Tpen是在 Canvas画线所使用的“笔”,因此所有和线条有关的绘图函数都会受 Tpen影响,如 LineTo、Ellipse、Polygon、PolyLine、Rectangle等函数都使用“笔”来画线,可以利用 Canvas.Pen 来存取 Pen,并且可以修改 Pen的性质,这些性质包含 Color、Width、Style,以及 Mode等。Style 属性用来设置画笔样式:

表示破折线+点线;=psClear表示透明线。

Pen->Style=psSolid,表示画笔是实心; =psDash表示破折线; =psDot表示点线; =psDashDot

Width属性用来设置画笔的宽度,Pen->Width=5表示画笔的宽度为 5个像素。

Color属性用来设定画笔的颜色。例如:Canvas->Pen->Color=clBlue;则表示将画笔的颜色设为 蓝色。Tbrush可用来在 Canvas的特定区域下着色。和 Tpen不同的是,Tbrush可以用不同的颜色、 样式及图案来填满 Canvas的特定区域,而 Tpen则是用来在 Canvas上画线。

Tbrush的 Style属性有 bsHorizontal、bsVertical、bsFDiagonal、bsBDiagonal、bsCross、bsDiagCross 几种,分别代表实心、透明、水平线、垂直线、左上到右下的斜线,左下到右上的斜线、垂直交叉

线、对角交叉线这几种填充方案。

其中 bsClear为默认值。

Tbrush的 Color属性设定与 Pen的 Color属性相一致。 6.常用的绘图函数

1)Canvas->MoveTo(int X, int Y);

函数用法:

MoveTo是用以在使用 LineTo之前设定画笔位置。使用此函数和直接设定 Canvas的 PenPos属 性的效果相同。

2)Canvas->LineTo(int X, int Y);

函数用法:

LineTo函数用来从画笔位置画一条至(X,Y)点的直线,此直线不包含(X,Y)点,同时将

画笔位置移至(X,Y)。所画的直线形状与 Pen的属性一致。

3)Canvas->Ellipse(int X1,int Y1,int X2,int Y2);

函数用法:

利用 Ellipse可在 Canvas上画出圆形或椭圆形。其环绕矩形的左上角坐标为(X1,Y1)而右下 角坐标为(X2,Y2)。若该矩形为正方形,则所绘图形为圆形。当此椭圆形绘制时,使用 Pen的值 画出其外框,而使用 Brush值填满其内部。

4)Canvas->Rectangle(int X1, int Y1, int X2,int Y2);

函数用法:

在 Canvas 上画出一矩形。其矩形的左上角坐标为(X1,Y1),而右下角坐标为(X2,Y2),矩

形内部的填充效果根据画刷的类型确定。

5)Canvas->Refresh()

函数用法: 清除画布。

1.2实例制作——用鼠标随意作图

1.程序设计思路

所谓在窗体上任意作图,就是要用鼠标在窗体上弹起弹落来确定所要画图形的起始位置,并设

定好 Pen和 Brush的各种属性,可在窗体上绘制直线、矩形、椭圆等图形。

2.程序实现步骤

※ 3※

(1)打开 C++Builder,生成一个新的应用程序,在工程中加入的组件如表 1所示。

o

加入的组件

Form cn w. ww Name Caption Name Name Caption Name Caption Name

ok 属性值 Form1 用鼠标随意作图 ColorDialog1 Button1 终止绘图 Button2 画直线 说明 表 1 工程中加入的组件及其属性 属性 .n ok et ColorDialog Button Button Button Button Caption Name Button3 画椭圆 Button4

bo

w. Caption 画矩形

Button Name .n Caption Button5 GroupBox Name 清屏 Caption GroupBox1 下面的组件放置在 Edit Name 画笔设定 GroupBox1 上面 Text Edit1 1 RadioButton Name Caption RadioButton1 RadioButton Name psSolid RadioButton2 Caption RadioButton Name psDash Caption RadioButton3 psDot RadioButton Name RadioButton4 bo Caption psDashDot Button Name Button6

Caption 颜色设置

GroupBox Name GroupBox2 下面的组件放置在

Caption 画刷设定 GroupBox2 上面

RadioButton Name RadioButton5 Caption bsSolid

RadioButton Name RadioButton6

Caption bsClear

RadioButton Name RadioButton7

Caption bsHorizontal

RadioButton Name RadioButton8 Caption bsVertical

Button Name Button7

Caption 颜色设置 设置好的程序界面如图 1所示。 w

w

o ok et

w .c

图 1 程序界面

※ 4※

o .n et et

ok

cn

w et

ok

.c .

(2)定义全局变量:

int sort,ox,oy; //sort代表要绘制图形的类别,ox、oy表示鼠标按下去时的坐标位置 (3)在生成窗体事件中初始化 sort,编写代码如下:

void __fastcall TForm1:: FormCreate(TObject *Sender)

{

sort=0; //表示不绘制图形 }

(4)设定画笔的宽度、颜色、形状。

编写代码如下:

(TObject *Sender) void __fastcall TForm1::Button6Click

{

if(ColorDialog1->Execute()) {

TColor pencolor;

Canvas->Pen->Color=ColorDialog1->Color; //设定画笔颜色 } }

void __fastcall TForm1::RadioButton1Click(TObject *Sender) {

Canvas->Pen->Style=psSolid ; //设定画笔为实线 }

void __fastcall TForm1::RadioButton2Click(TObject *Sender) {

Canvas->Pen->Style=psDash ; //设定画笔为破折线

}

cn ok

void __fastcall TForm1::RadioButton3Click(TObject *Sender) {

Canvas->Pen->Style=psDot; //设定画笔为点线 }

void __fastcall TForm1::RadioButton4Click(TObject *Sender)

{

//设定画笔为点线+破折线 Canvas->Pen->Style=psDashDot ;

}

void __fastcall TForm1::Edit1Change(TObject *Sender) {

Canvas->Pen->Width=StrToInt(Edit1->Text); //设定线宽

}

)设定画刷的颜色、形状,编写代码如下: (5

void __fastcall TForm1::Button7Click(TObject *Sender) {

if(ColorDialog1->Execute())

{ TColor pencolor;

Canvas->Brush->Color=ColorDialog1->Color; //设定画刷的颜色

}

}

void __fastcall TForm1::RadioButton5Click(TObject *Sender)

{

Canvas->Brush->Style=bsSolid; //设定画刷为实心

※ 5※

o

}

cn ok

void __fastcall TForm1::RadioButton6Click(TObject *Sender) {

Canvas->Brush->Style=bsClear; //设定画刷为透明 }

void __fastcall TForm1::RadioButton7Click(TObject *Sender) {

Canvas->Brush->Style= bsHorizontal; //设定画刷为水平填充 }

void __fastcall TForm1::RadioButton8Click(TObject *Sender) { Canvas->Brush->Style= bsVertical; //设定画刷为垂直填充 }

(6)确定下一步是画椭圆、画直线、画矩形、清屏还是终止绘图,编写如下的代码: void __fastcall TForm1::Button1Click(TObject *Sender) {

sort=0;

} void __fastcall TForm1::Button2Click(TObject *Sender) {

sort=1; }

void __fastcall TForm1::Button4Click(TObject *Sender) {

sort=2;

}

void __fastcall TForm1::Button3Click(TObject *Sender) {

sort=3;

}

void __fastcall TForm1::Button5Click(TObject *Sender) {

Canvas -> Refresh();

}

(7)记录下鼠标在窗体上按下的坐标,即确定所要画图形的起始位置,编写如下的代码:

void __fastcall TForm1::FormMouseDown( TObject *Sender, TMouseButton Button,TShiftState

Shift, int X, int Y)

{

ox=X;

oy=Y;

}

(8)编写鼠标在弹起时程序所要做的工作,编写如下的代码:

void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,TShiftState Shift,

int X, int Y)

{

switch(sort)

{ case 1 :

Canvas->MoveTo(ox, oy);

Canvas->LineTo(X, Y);

※ 6※

o

ok

break;

cn case 2 :

Canvas -> Rectangle(ox,oy,X, Y); break; case 3:

Canvas -> Ellipse(ox,oy,X, Y); break;

}

}

(9)程序编译运行,可在窗体上随意画出各种图形组合,如图 2所示。

ww

.n bo .n

图 2程序运行结果图

3.程序分析与说明

本例所画的图形在窗体重新调整大小时都自动消失,这是因为程序没有在 FormPaint事件中绘 图。在 FormPaint事件中绘制的图形不会在窗体调整时自动消失。

2彩色图变黑白图

2.1知识要点

1. Image 组件

Image组件用来装载图像文件和在程序中显示图像。Image组件位于 Additional组,该组件在模 板中的位置如图 3所示(图中提示信息上方的按钮)。

Image的属性包括 Canvas(画布),用法如同

图 3etImage 组件

ok 1节知识要点所介绍。此外,它还有别的常用属性,如表 2所示。

表 2 Image组件的常用属性

属性 取值范围 作用 说明 ww AutoSize true Image组件的长度宽度自动调整为装载的图 图像长度宽 像长度宽度 度保持不变 false Image组件的长度宽度不变,默认值 Stretch true 装载的图像缩放为false Image组件的长度宽度 Image组件的 长度宽度保 装载的图像不缩放,默认值 Picture 表示文件路径和 指定组件所装载的图形文件 文件名的字符串 持不变 Visible true 图像可见 false 图像不可见 Transparent true 装载的图像背景透明 false 图像背景不透明 w ww Image

的函数: ※ 7 ※

o ok .n et

w ww .c

ok

LoadFromFile(String filename )cn ;

函数用法: LoadFromFile是将图形文件加载到 Image组件中。

例如要将 C盘 image文件夹中名为 image1.bmp的图形文件加入到 Image1

组件,可在程序中加

入如下代码:

Image1->Picture-> LoadFromFile(\

); 2. GetRValue、GetBValue和 GetGValue

这三个 API函数是用来在颜色值中析取红、绿、蓝的强度值,分别返回一个 0~255的亮度值。

函数原型:

BYTE GetRValue(TColor color); BYTE GetGValue(TColor color); BYTE GetBValue(TColor color);

使用范例:

BYTE nRed ,nBlue ,nGreen;

TColor color= RGB(4, 34, 253); nRed = GetRValue(color);

nGreen = GetGValue(color); nBlue = GetBValue(color); 结果说明:

nRed=4;nBlue =34;nGreen=253; 3. ScanLine

C++Builder提供了 ScanLine处理技术读取整行的像素颜色值,提高了图像处理的速度。

使用范例:

Graphics:: TBitmap *bitmap1;

Byte *newscan; newscan= static_cast (bitmap1->ScanLine[0]); //newscan指向位图 bitmap1的第 1行所有像素点的颜色值 参数说明:

Tbitmap是位图类,封装了许多进行图像处理的属性和方法,其中包括了 Canvas属性和 ScanLine 方法。

2.2实例制作——逐点实现彩色图变成黑白图

1.程序设计思路

先用 Image组件将图像装载进来。从左到右,从上到下,使用 Image的 Canvas的 Pixels属性逐 点取得每一个像素点的

color值,然后使用 GetRValue、GetBValue和 GetGValue函数析取红绿蓝的 强度值,加以平均,即红、绿、蓝的强度值一样。将新的颜色值再赋给 Image的每一点的 Pixels属 性,即将彩色图变成黑白图。

2.程序实现步骤

(1)打开 C++Builder,生成一个新的应用程序。往窗体中加入的组件如表

3所示。

表 3窗体中加入的组件及其属性

加入的组件 属性Form ok 属性值 Name Form1 Caption 彩色图变黑白图示例 Image Name Image1 AutoSize true OpenPictureDialog Name Button Name OpenPictureDialog1 Button1 Caption 打开图像 ※ 8 ※

et o ok .n

w

Button cn 加入的组件 ok 续表 3

属性 Name Caption Name Caption 属性值 Button2 点像素变黑白 et

et ok Button Button3 快速变黑白 设置好的程序界面如图 4所示。

w.

et ok

图 4设置好的程序界面

et

(2)在 Unit7_1.cpp开头部分定义全局变量:

Graphics::TBitmap *bitmap1; Graphics::TBitmap *bitmap2;

int x,y; //x存放图像的宽度,y存放图像的高度

(3)编写单击 Button1的 OnClick事件,实现装载图片到 Image1中(目前 Image装载的是 Bmp 图片,4节会介绍如何装载显示 jpeg图片)。编写如下代码:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

bitmap1=new Graphics::Tbitmap;

bitmap2=new Graphics::Tbitmap;

String openname,extension;

if(OpenPictureDialog1->Execute()) {

openname=OpenPictureDialog1->FileName;

extension=openname.SubString(openname.Length()-2,3);

Image1->Picture->LoadFromFile(openname);

) //如果是 Bmp图片 if(LowerCase(extension)==\

{

bitmap1->LoadFromFile(openname);

bitmap2->LoadFromFile(openname);

x=bitmap1->Width;

y=bitmap1->Height;

bitmap1->PixelFormat=pf24bit;

bitmap2->PixelFormat=pf24bit;

Image1->Picture->Bitmap->Assign(bitmap1);

}

}

}

(4)编写单击 Button2的 OnClick事件,实现彩色图变成黑白图。编写如下代码:

void __fastcall TForm1::Button2Click(TObject *Sender)

{

int rgb,i,j,r,g,b;

TColor color;

for(i=0;iWidth;i++)

{

for(j=0;jHeight;j++)

※ 9※

o

{

cn ok

} }

color= Image1->Canvas->Pixels[i][j]; r=GetRValue(color); g=GetGValue(color); b=GetBValue(color); rgb=(r+g+b)/3;

Image1->Canvas->Pixels[i][j]=RGB(rgb,rgb,rgb);

}

(5)保存编译运行,2.3节还会继续用到这个工程文件。

3.程序分析与说明

逐点实现彩色图变成黑白图,方法非常简单,易用,但是非常费时,所以程序运行时,尽量选 取字节比较小的图片文件来进行处理。

——用 ScanLine方法实现彩色图快速变黑白图 2.3实例制作

1.程序设计思路

(1)将图像装载到 bitmap位图中,从上到下,使用 ScanLine处理技术逐行读取像素颜色值。 (2)使用 GetRValue、GetGValue和 GetBValue函数析取红绿蓝的强度值,加以平均。 (3)使用 ScanLine处理技术,逐行将新的颜色值赋给 bitmap位图。 2.程序实现步骤

(1)打开本文 2.2节中保存的工程文件,编写单击 Button3的 OnClick事件,实现彩色图快速

变成黑白图。编写如下代码:

void __fastcall TForm1::Button3Click(TObject *Sender)

{

Byte *ptr,*newscan;

Byte r,g,b,bgr;

bitmap1->Assign(Image1->Picture->Graphic); for(int i=0;i

ptr=static_cast(bitmap1->ScanLine[i]);

newscan= static_cast(bitmap2->ScanLine[i]);

for(int j=0; j

{

b=ptr[j*3]; g=ptr[j*3+1];

r=ptr[j*3+2];

b+g+r)/3; bgr=(

newscan[j*3]=(Byte)bgr; newscan[j*3+1]=(Byte)bgr;

newscan[j*3+2]=(Byte)bgr;

}

}

Image1->Picture->Bitmap->Assign(bitmap2);

}

(2)编译运行程序,单击 Button1选取一个 Bmp图片,再单击 Button3,彩色图能够快速变成

黑白图。

3.程序分析与说明

要进行快速的图像处理,几乎都离不开 ScanLine技术。而用 ScanLine技术取得的 bitmap每行

的颜色,其存放顺序是从左到右,每一点的蓝色、绿色、红色的亮度值,而不是红色、绿色、蓝色 的次序,这一点要特别注意。

※ 10※

o

3实现图像的特殊显示效果

3.1知识要点

cn ok

的计算机系统,完成一个 for循环:

for(int i=0;i<10000;i++) { j=j+1;

}

可能也只是在一瞬间就完成了。而在实现图像的特殊显示效果时,需要在一个过程的完成后, 等待一定的时间,才运行程序下面的代码,这时就要使用到时间的延迟了。

Sleep函数只有一个整型参数 cMilliseconds,用来指定需要延迟的时间,它的单位是毫秒。例如 在程序中加入下面的代码:

1. Sleep函数

Sleep函数是系统的 API函数库里提供的时间延迟函数。延迟在程序设计中非常有意义。现在

ShowMessage(\现在开始计时\); Sleep(3000); //延迟三秒 ShowMessage(\延迟了三秒!\);

程序运行时在弹出“现在开始计时”的对话框后,程序在延迟了三秒钟的时间后,才弹出“延

2. rand()、random()、Randomize() 这三个随机函数是用来产生一个随机数。

int rand()函数,它返回一个不大于 RAND_MAX的随机数。RAND_MAX是能够产生的最大

迟了三秒!”对话框。

随机数。

int random(int num);它返回一个不大于 num的随机数。

其中 Number参数是可选的,是变量或任何有效的数值表达式。Randomize用 Number将 rand函数

Randomize(int Number);为产生一个随机数,应先执行 Randomize来初始化随机数生成器。

的随机数生成器初始化。如果省略 Number,则用系统计时器返回的值作为新的种子值。如果没有 使用 Randomize,则无参数的 Rand函数将使用第一次调用 Rand函数时的种子值。在使用随机函数

时,必须加入

int max=RAND_MAX;

Randomize();

int x=255*rand()/max; int y=random(100);

则 x的取值介于 0~255之间,y的取值介于 0~99之间。

3.2实例制作—— 图像淡入淡出效果

逐步均匀的增加图像各像素点的颜色值,直到恢复为原图。在这每一步中,都加入一定的时间延迟, 以实现程序中图像淡入的效果。图像淡出效果则与之相反,即逐步均匀的减少图像各像素点的颜色 值,直到图像各像素点的颜色值都变为黑色。

2.程序实现步骤

1.程序设计思路

图像淡入效果就是在一幅图像装载到 Image组件后,将图像各像素点的颜色值都置为黑色,再

(1)打开 C++Builder,生成一个新的应用程序。往窗体中加入的组件如表 4所示。

加入的组件 Form 表 4窗体中加入的组件及其属性 属性 属性值 Form1 2图像特殊显示效果 说明 Name Caption ※ 11※

et o

加入的组件

Image cn w. ww Name Name

ok bo 属性值 Image1 true OpenPictureDialog1 Button1 打开图像 Button2 图像淡入 Button3 图像淡出 Button4 说明

续表 4

根据装载的图像大小自 动调整 Image1的大小 属性 .n ok et

Name AutoSize OpenPictureDialog Button Button Button Button Caption Name Caption Name Caption Name Caption 马赛克显示 et Button Name Button5 Caption 设置好的程序界面如图

5所示。

透明显示 ok

ok cn

. cn ww

(2)在

Unit7_2.cpp开头部分,加入头文件和定义全局变量:.n 图 5设置好的程序界面

bo

#include #include

Graphics::TBitmap *bitmap1; Graphics::TBitmap *bitmap2; Byte *ptr,*newscan; int x,y;

(3)在生成窗体事件中初始化 bitmap1

、bitmap2,编写如下代码: void __fastcall TForm1::FormCreate (TObject *Sender) { bitmap1 = new Graphics::TBitmap ();

bitmap2 = new Graphics::TBitmap ();//生成 Tbitmap类的实例

}

(4

)编写单击 Button1的 OnClick事件,实现利用对话框,将图形文件加载到 Image1组件, 并取得 bitmap1的长度和宽度。编写如下代码:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ String openname;

if(OpenPictureDialog1->Execute()) {

openname=OpenPictureDialog1->FileName;

Image1->Picture->LoadFromFile

(openname); bitmap1->LoadFromFilebitmap2->LoadFromFile

(openname);

(openname);

bitmap1->PixelFormat=pf24bit;

bitmap2->PixelFormat=pf24bit; x=bitmap1->Width;

※ 12※

o

.n

}

y=bitmap1->Height;

cn ok

}

20次均匀的变化,bitmap2 (5)编写单击 Button2的 OnClick事件,使得 bitmap1保持不变,经过

里的值由 0变为原始值。编写如下代码:

void __fastcall TForm1::Button2Click(TObject *Sender)

{

; bitmap2->Assign(Image1->Picture->Graphic)

bitmap1->Assign(Image1->Picture->Graphic); Byte r,g,b,bgr;

for(int i=0;i

{ newscan= static_cast(bitmap2->ScanLine[i]);

for(int j=0; j

{

newscan[j*3]=0;

newscan[j*3+1]=0;

newscan[j*3+2]=0;

} }

Image1->Picture->Bitmap->Assign(bitmap2); //设置整幅图为黑色

for(int l=0;l<20;l++) //L的取值代表着像素颜色变化的次数 {

for(int i=0;i

{

ptr=static_cast(bitmap1->ScanLine[i]); //bitmap1保持不变 newscan= static_cast(bitmap2->ScanLine[i]);

int j=0; j

{

b=ptr[j*3];

g=ptr[j*3+1];

r=ptr[j*3+2];

bgr=(b+g+r)/3; newscan[j*3]=l*b/20; newscan[j*3+1]=l*g/20;

newscan[j*3+2]=l*r/20; //bitmap2渐变、图像淡入

}

}

Image1->Picture->Bitmap->Assign(bitmap2); Form1->Refresh(); //窗体重画

); //Image1每一次变化后程序停顿 1秒钟,以便观测到图 Sleep(1000

像淡入的效果

}

Image1->Picture->Bitmap->Assign(bitmap1); //恢复原图

}

(6)编写单击的 Button3的 OnClick事件,使 bitmap1保持不变,经过 20次均匀的变化,bitmap2 里的值由原始值变为 0。编写如下代码:

void __fastcall TForm1::Button3Click(TObject *Sender)

{

bitmap2->Assign(Image1->Picture->Graphic);

bitmap1->Assign(Image1->Picture->Graphic);

Byte r,g,b; for(int l=0;l<20;l++)

{

for(int i=0;i

※ 13※

o

{

cn ok

ptr=static_cast(bitmap1->ScanLine[i]);

newscan= static_cast(bitmap2->ScanLine[i]);

for(int j=0; j

{

b=ptr[j*3];

g=ptr[j*3+1];

r=ptr[j*3+2];

newscan[j*3]=b-l*b/20; newscan[j*3+1]=g-l*g/20; newscan[j*3+2]=r-l*r/20; //bitmap2渐变、图像淡出 }

}

Image1->Picture->Bitmap->Assign(bitmap2); Form1->Refresh(); //窗体重画

Sleep(1000); //Image1每一次变化后程序停顿 1秒钟,以便观测到图 像淡出的效果}

for(int i=0;i

{

newscan= static_cast(bitmap2->ScanLine[i]);

for(int j=0; j

newscan[j*3]=0; newscan[j*3+1]=0; newscan[j*3+2]=0;

}

} //设置整幅图为黑色

Image1->Picture->Bitmap->Assign(bitmap2);

}

(7)保存文件,编译运行程序,3.3节还会继续用到这个工程文件。

3.程序分析与说明

使用 Sleep,要注意延迟时间参数 t的设定,使图像渐变的过程能够被清楚地观察到。

3.3实例制作——图像的马赛克现象

1.程序设计思路

图像的马赛克是指图像被分割成许多的小方块以随机的顺序显示出来直到恢复原图。 2.程序实现步骤

(1)打开 3.2节保存好的程序文件,编写 Button4的 OnClick事件,使图像所有的像素点全部 变黑。然后每次显示图像中一个位置随机的 50*50的方块,如此循环 500次。最后显示整个图像。

编写的代码如下:

void __fastcall TForm1::Button4Click(TObject *Sender) {

int x1,x2,y1,y2;

bitmap1->Assign(Image1->Picture->Graphic) ; for(int i=0;i

newscan= static_cast(bitmap2->ScanLine[i]);

for(int j=0; j

{

newscan[j*3]=0;

newscan[j*3+1]=0; newscan[j*3+2]=0;

※ 14※

o

}

cn ok

}

Image1->Picture->Bitmap->Assign(bitmap2);

Form1->Refresh();

int max=RAND_MAX; Randomize();

for(int l=0;l<500;l++)

{

x1=x*rand()/max; //产生随机方块的左顶点的横坐标

y1=y*rand()/max; //产生随机方块的左顶点的纵坐标

x2=x1+50;

y2=y1+50; if(x2>x) {

x1=x; }

if(y2>y) {

y2=y;

}

for(int i=y1;i

ptr= static_cast(bitmap1->ScanLine[i]);

newscan= static_cast(bitmap2->ScanLine[i]); for(int j=x1; j

newscan[j*3]=ptr[j*3];

newscan[j*3+1]=ptr[j*3+1];

newscan[j*3+2]=ptr[j*3+2]; //随机显示 50*50的一块图像

} }

Image1->Picture->Bitmap->Assign(bitmap2); Form1->Refresh(); //窗体重画 Sleep(100); }

Image1->Picture->Bitmap->Assign(bitmap1); //恢复原图

}

(2)保存文件,编译运行。 3.程序分析与说明

由于随机函数的随机性,每执行一次程序,图像变化的过程都不一样。

显示透明位图 3.4实例制作——

1.程序设计思路

位图透明显示,是指将图像显示在背景上时,指定某种颜色为透明色,图像上透明色不被显示

出来,而保持该处的背景颜色。在默认情况下,以位图最左下角像素的颜色为透明色。要实现透明 位图的显示,可以采用 2个 Timage组件叠放在同一位置,将背景图置于下方,进行图像合成。设 定要做透明显示的 Timage组件的 Transparent属性为 true,即为透明,并指定透明色,这种方法简 单有效,并且对背景图像的类型和格式不作要求。

2.程序实现步骤 加入如下代码:

(1)打开 3.3节所保存好的程序文件,编写 Button5的 OnClick事件,将 Image1图像透明显示, void __fastcall TForm1::Button5Click(TObject *Sender) {

※ 15※

o

Image1->Transparent=true;

bitmap1->TransparentColor=bitmap1->Canvas->Pixels[3][3]; //指定透明色

Image1->Picture->Bitmap->Assign(bitmap1);

}

(2)编译运行该程序,可以实现图像特殊的显示效果。 3.程序分析与说明

cn ok

图像的特殊显示效果,其实质是将图像的各个像素点的颜色加以有规律的变化,使用 Sleep函

数来延迟这一变化过程。常见的特殊显示效果还有百叶窗显示,图像柔化和锐化等等。

4图片的相互转换

4.1知识要点

TJPEGImageC++Builder提供了 类。

TJPEGImage类来支持 JPEG图像,调用 TJPEGImage的 SaveToFile

方法可

以将位图文件保存为 JPEG图像。要使用 TJPEGImage,必须加入这个头文件。 TJPEGImage

的常用属性及说明如表 5所示。

表 5 TJPEGImage的常用属性及说明

属性 用途 取值范围 CompressionQuality 设置 JPEG图像的清晰 1~ 100,效果由差到好 度 Empty 检查是否装载有图像 true和 false Height 表示装载图像的高度 非负的整数 Width 表示装载图像的宽度 非负的整数

PixelFormat 描述图像颜色的位数 bo 8, 24 方法有 AssignTJPEGImage.n

Tbitmap *bitmap的主要):; 函数用法:

如下段代码所描述,使用 Assign,Timage组件的 Picture属性的 Bitmap

被赋给了 jpg1。

TJPEGImage *jpg1;

jpg1=new TJPEGImage

jpg1->Assign(Image1->Picture->Bitmap);

jpg1->SaveToFile(savename); SaveToFile(String filename) 函数用法:

如上段代码使用 SaveToFile

方法,TJPEGImage类的图像被保存为 JPEG格式的文件。

4.2实例制作—— JPEG图像和 bmp图像的相互转换

1.程序设计思路

C++Builder 6的 TImage控件直接支持 Bitmap格式(.bmp)、Icon

格式(.ico)、Metafile格式(.emf

or .wmf)和 JPEG格式的图像文件的打开显示。在程序设计中可以把这几种格式的文件直接赋给 TImage控件的 Picture属性。但是为了实现 JPEG图像和

bmp图片的相互保存转换,就必须在程序

中加入 TJPEGImage类和 Tbitmap类。

为实现将位图保存为 JPEG格式的文件,就必须将 TImage控件的 Picture属性的 Bitmap赋给

TJPEGImage,然后利用 TJPEGImage

为实现将 JPEG格式保存为位图,就必须将 的 SaveToFile方法来保存 JPEG图像。

TImage控件的 Picture属性的 Graphic赋给 Tbitmap,

然后利用 Tbitmap的 SaveToFile

方法来保存位图图像。 2.程序实现步骤

(1)打开 C++Builder,生成一个新的应用程序。往窗体加入的组件及其属性如表

※ 16※

6所示。

o

.

.n

cn w. ww 加入的组件 Form

ok 属性 属性值 Form1 Jpeg图像和 Bmp图像的相互转换 Image1 true OpenPictureDialog1 SavePictureDialog1 Button1 打开图像 Button2 保存图像 表 6加入的组件及其属性Name Caption Name AutoSize Name Name Name Caption Name Caption

et Image OpenPictureDialog SavePictureDialog Button Button ok

ww

设定好的程序界面如图 6所示。

ok cn ok

图 6设定好的程序界面

(2)定义头文件和全局变量。 #include

String openname; //openname表示打开图像的文件名

String extension; //extension表示打开图像的文件名的扩展名

(3)编写单击 Button1 的 OnClick事件,打开一幅图像,装载到 TImage控件的 Picture属性中, 编写代码如下:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

if(OpenPictureDialog1->Execute()) {

openname=OpenPictureDialog1->FileName;

extension=openname.SubString(openname.Length()-2,3); Image1->Picture->LoadFromFile(openname ); }

}

(4)编写单击 Button2的 OnClick 事件,实现 JPEG图像和 bmp图像的相互转换,编写代码如 下:

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Graphics::TBitmap *bitmap1;

bitmap1=new Graphics::TBitmap; //生成 TBitmap类的实例 TJPEGImage *jpg1;

类的实例 jpg1=new TJPEGImage; //生成 TJPEGImage

if(SavePictureDialog1->Execute()) {

String savename=SavePictureDialog1->FileName;

String exten=savename.SubString(savename.Length()-2,3);

if((UpperCase(exten)==\(exten)==\)&& UpperCase(extension)

==\)

//将位图保存为 JPEG格式的文件

{

(Image1->Picture->Bitmap); jpg1->Assign

jpg1->SaveToFile(savename);

※ 17※

o

}

else if((UpperCase(exten)==\(UpperCase(exten extension)==\)

|| UpperCase(extension)==\))

//将 JPEG格式保存为位图

{

bitmap1->Assign(Image1->Picture->Graphic);

bitmap1->SaveToFile(savename);

} else

Image1->Picture->SaveToFile(savename); //同一图片格式的保存

}

}

(5)运行该程序,就可以实现 JPEG图像和 BMP图像的显示以及它们之间的相互转换。 3.程序分析与说明

cn ok

在使用保存图像文件对话框时,一定要将保存文件的扩展名也写出来,不然程序会认为此文件 没有扩展名,导致程序出错。

5字体修饰

5.1知识要点

1. Tcanvas的 Font属性

Font性质是用来控制 Canvas上的文字所使用的字体格式。

、Name、Size、Style等方式来分别改变字体的颜色、使用的字体 在程序中可以利用设定 Color

名称、字体大小及字体的样式。

1)Color属性 2)Size属性

Tfont的 Color性质和其他组件的 Color属性相同,用来设置字体的颜色。

Size属性表示字体的大小,以磅为单位。例如可以设定: Canvas->Font->Size=12; 3)Style属性

Style属性用以表示字体的样式。它包含以下几种样式:

fsBold:粗体。 fsItalic:斜体。 fsUnderline:有下划线。

fsStrikeOut:穿越文字的水平直线。 4)Name属性

Name属性表示使用字体的名称。可以用以下的方式来设定字体名称: Canvas->Font->Name=\楷体\ //设定字体为楷体 2. TextOut函数

函数原型:

Canvas->TextOut(int X,int Y,String Text); 参数说明:

使用该函数就是在 Canvas上指定的坐标输出指定的文本。

5.2实例制作——显示三维文字

1.程序设计思路

在程序中添加一个设置字体的对话框,作为设定显示文本的字体格式。利用 TextOut 在窗体中 指定的位置显示输入的文字。再将指定的位置稍微错位,叠加显示输入的文字,依次重复若干次,

※ 18※

o

就可以得到比较满意的三维文字效果。

2.程序实现步骤

Form cn ok

(1)打开 C++Builder,生成一个新的应用程序。往窗体中加入的组件如表 7所示。

表 7窗体中加入的组件及其属性

属性 Name Caption Name Name Caption Name 加入的组件 属性值 .n ok Form1 显示三维文字 FontDialog1 Button1 设定字体 Button2 FontDialog Button Button

Caption 输入文字 Button Name Button3 Caption 显示 3维文字 设定好的程序界面如图

7所示。

ok

ok cn

. cn ww

设定好的程序界面

(2)定义全局变量:

String str; //表示要显示的文本

TColor fontcolor; (3)编写单击 //用来保存三维文字表层的颜色 Button1的 OnClick事件,设定字体的格式,编写代码如下: void __fastcall TForm1::Button1Click (TObject *Sender) {

if(FontDialog1->Execute()==true) //打开设定字体的对话框 {

Canvas->Font->Name=FontDialog1->Font->Name; // 设定字体名称

Canvas->Font->Size=FontDialog1->Font->Size;

//设定字体大小 fontcolor=FontDialog1->Font->Color; //设定字体颜色

}

}

(4)编写单击 Button2 的 OnClick事件,输入要显示的文本,编写代码如下: void __fastcall TForm1::Button2Click {

(TObject *Sender)

str = InputBox(\请输入要显示的文字:\你好,中国!\);

//利用 InputBox函数来输入要显示的文本

}

(5)编写单击 Button3的 OnClick事件,实现刷新屏幕,编写代码如下:

void __fastcall TForm1::Button3Click(TObject *Sender ) {

Refresh();

}

(6)编写窗体的 FormPaint事件,实现三维文字的显示,编写代码如下:

void __fastcall TForm1::FormPaint (TObject *Sender)

{ int i,l; Canvas->Brush->Style=bsClear; //设定画刷格式

※ 19※

o et

图7

.n

ok

l=Canvas->Font->Size;

cn l=l/3; //l用来根据要显示文字的字体大小来设定三维文字的效果for(i=100;i<(100+l);i++)

{

Canvas->Font->Color=RGB(255-i,255-i,255-i);

Canvas->TextOut(i,i,str); //错位叠加显示三维文字的阴影部分

}

Canvas->Font->Color=fontcolor;

Canvas->TextOut(i,i,str); //显示三维文字的表层}

(7)编译运行,程序运行结果是:单击 “输入文字”按钮,在弹出的如图 8所示的对话框中输

入“你好,中国!”。

.n

图 8输入对话框

(8)单击“OK”按钮返回。单击“设定字体”按钮,在弹出的如图

9所示的对话框中设定字

体格式。

bo.n w. bo

图 9“字体”对话框

(9)单击“显示 3维文字”按钮,就可以在窗体上得到如图 10所示的三维文字。

ww

.n bo

图 10程序生成的三维文字

3.程序分析与说明

三维文字的显示形式是多姿多彩的,例如,可以在本例介绍的

FormPaint函数中,改变 i,l的取值,就可以获得不同效果的三维文字:

在 FormPaint中的代码“Canvas->Font->Color=fontcolor;”的后面,加一句

“i=100;”,就可以得 到如图 11所示的三维文字。

w.c o w

图 11程序生成的另一形式的三维文字 ※ 20※

o

.

.n

本文来源:https://www.bwwdw.com/article/i4ag.html

Top