}
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
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;i
{
for(j=0;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 newscan= static_cast 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