-
c语言入门之用C++ Builder对图像进行特殊效果处理
在Windows编程中图像处理相对比较复杂,好在C++ Builder提供了一些图形类,它们通过对Windows中的图形对象进行包装,从而大大简化了图像操作的难度。下面就通过对图像进行柔化、锐化、浮雕效果等几个特殊效果处理来具体说明一下。
一、准备工作 位图图形实际上是像素的二维数组,它记录了每个像素的颜色信息,而TCanvas类提供了Pixels属性,用它可以存取指定像素的颜色值,通过这个属性将位图图形的部分或全部像素的颜色值进行相应的变换处理,就可以实现图像的特殊效果处理。在Windows中颜色是根据红、绿、蓝三种颜色的饱和度来定义的,在这里我们要将像素颜色值的红、绿、蓝分量从像素值中分离出来,分别加以保存,所以需要定义一个结构来存放颜色分量:
struct rgb_str{
unsigned char r_color;
unsigned char g_color;
unsigned char b_color;};
rgb_str rgb[2000][2000];
建立全局变量:Graphics::TBitmap *bitmap;
//用来存放变换后的位图
int i,j,width,height;
在窗体上放置一个TImage组件和OpenPictureDialog组件,将TImage的AutoSize属性设为true,将OpenPictureDialog的Filter设为*.bmp。当用户选择Open命令后,打开相应的对话框,让用户选择要处理的图像文件,然后程序将图像的所有像素的颜色分量保存到rgb数组中:
void __fastcall TForm1::mnuFileOpenClick
(TObject *Sender)
{ TColor color;
if(OpenPictureDialog1- >Execute()){
Image1- >Picture->LoadFromFile
(OpenPictureDialog1- >FileName);
width=Image1- >Picture- >Width; height=Image1->Picture->Height;
for(i=0;i< width-1;i++)
for(j=0;j< height-1;j++)
{ color=Image1- >Canvas->Pixels[i][j];
rgb[i][j].r_color=GetRvalue(color);
rgb[i][j].g_color=GetGvalue(color);
rgb[i][j].b_color=GetBvalue(color);
}
bitmap=new Graphics::TBitmap;
bitmap- >Width=width;
bitmap- >Height=height;
}
}
二、图像的柔化处理
柔化就是对图像进行平滑处理,减少相邻像素间的颜色差别,一般选用3*3像素块,将中间的像素值改成这9个像素的平均像素值,从而达到柔化效果。其代码如下:
void __fastcall TForm1::btnSmoothClick
(TObject *Sender)
int red,green,blue;
for(i=1;i< width-2;i++)
for(j=1;j< height-2;j++)
{ red=rgb[i-1][j-1].r_color+rgb[i][j-1].r
_color+rgb[i+1][j-1].r_color+
rgb[i-1][j].r_color+rgb[i][j].r
_color+rgb[i+1][j].r_color+
rgb[i-1][j+1].r_color+rgb[i][j+1].r
_color+rgb[i+1][j+1].r_color;
green=rgb[i-1][j-1].g_color+rgb[i][j-1].g
_color+rgb[i+1][j-1].g_color+
rgb[i-1][j].g_color+rgb[i][j].g
_color+rgb[i+1][j].g_color+
rgb[i-1][j+1].g_color+rgb[i][j+1].g
_color+rgb[i+1][j+1].g_color;
blue=rgb[i-1][j-1].b_color+rgb[i][j-1].b
_color+rgb[i+1][j-1].b_color+
rgb[i-1][j].b_color+rgb[i][j].b
_color+rgb[i+1][j].b_color +
rgb[i-1][j+1].b_color+rgb[i][j+1].b
_color+rgb[i+1][j+1].b_color;
bitmap- >Canvas- >Pixels[i][j]
=RGB(red/9,green/9,blue/9);
}
Image1- >Picture- >Bitmap- >Assign(bitmap);
}
三、图像的锐化处理
图像的锐化处理正好与柔化处理相反,它的目的是突出图像的变化部分,这里采用的算法是将要处理的像素与它左对角线的像素之间的差值乘上一个锐化度数,然后再加上原先的像素值:new_value=original_value+degree*difference,你可以通过改变degree的值来调节锐化效果。这里需要注意的是得到的像素新值可能会超出颜色值的有效范围(0-255),所以程序要检验结果的有效性,为此需定义两个函数:
int min(int value1,int value2)
{ if(value1 >value2)return value2;
else return value1;
}int max(int value1,int value2)
{ if(value1 >value2)return value1;
else return value2;}
锐化处理的代码如下:
void __fastcall TForm1::btnSharpeClick
(TObject *Sender)
{
float degree=0.3;
int red,green,blue;
for(i=1;i< width-1;i++)
for(j=1;j< height-1;j++)
{ red=rgb[i][j].r_color+degree*(rgb[i][j].r
_color-rgb[i-1][j-1].r_color);
green=rgb[i][j].g_color+degree*(rgb[i][j].g
_color-rgb[i-1][j-1].g_color);
blue=rgb[i][j].b_color+degree*(rgb[i][j].b
_color-rgb[i-1][j-1].b_color);
red=min(255,max(0,red));
green=min(255,max(0,green));
blue=min(255,max(0,blue));
bitmap- >Canvas->Pixels[i][j]=RGB (red,green,blue);
} Image1- >Picture- >Bitmap- >Assign(bitmap);
}
四、图像的浮雕效果实现
浮雕效果就是只将图像的变化部分突出出来,而相同颜色部分则被淡化,使图像出现纵深感,从而达到浮雕效果,这里采用的算法是将要处理的像素取值为与处于对角线上的另一个像素间的差值,这样只有颜色变化区才会出现色彩,而颜色平淡区因差值几乎为零则变成黑色,你可以通过加上一个常量来增加一些亮度:new_value=difference+const_value,具体代码如下:
void __fastcall TForm1::btnEmbossClick
(TObject *Sender)
{ int red,green,blue;
const int const_value=128;
for(i=0;i< width-2;i++)
for(j=0;j< height-2;j++)
{ red=abs(rgb[i][j].r_color-rgb[i+1][j+1].r
_color+const_value);
}
green=abs(rgb[i][j].g_color-rgb[i+1][j+1].g
_color+const_value);
blue=abs(rgb[i][j].b_color-rgb[i+1][j+1].b_
color+const_value);
bitmap- >Canvas- >Pixels[i][j]=RGB
(red,green,blue);
}
Image1- >Picture- >Bitmap- >Assign(bitmap);
}
上面介绍了图像处理中的几个常见操作,所采用的算法相对比较简单,感兴趣的朋友可以举一返三,通过改进上述算法,达到更好的特殊效果。以上代码在C++ Builder3、Pwin98下编译、运行通过。
一、准备工作 位图图形实际上是像素的二维数组,它记录了每个像素的颜色信息,而TCanvas类提供了Pixels属性,用它可以存取指定像素的颜色值,通过这个属性将位图图形的部分或全部像素的颜色值进行相应的变换处理,就可以实现图像的特殊效果处理。在Windows中颜色是根据红、绿、蓝三种颜色的饱和度来定义的,在这里我们要将像素颜色值的红、绿、蓝分量从像素值中分离出来,分别加以保存,所以需要定义一个结构来存放颜色分量:
struct rgb_str{
unsigned char r_color;
unsigned char g_color;
unsigned char b_color;};
rgb_str rgb[2000][2000];
建立全局变量:Graphics::TBitmap *bitmap;
//用来存放变换后的位图
int i,j,width,height;
在窗体上放置一个TImage组件和OpenPictureDialog组件,将TImage的AutoSize属性设为true,将OpenPictureDialog的Filter设为*.bmp。当用户选择Open命令后,打开相应的对话框,让用户选择要处理的图像文件,然后程序将图像的所有像素的颜色分量保存到rgb数组中:
void __fastcall TForm1::mnuFileOpenClick
(TObject *Sender)
{ TColor color;
if(OpenPictureDialog1- >Execute()){
Image1- >Picture->LoadFromFile
(OpenPictureDialog1- >FileName);
width=Image1- >Picture- >Width; height=Image1->Picture->Height;
for(i=0;i< width-1;i++)
for(j=0;j< height-1;j++)
{ color=Image1- >Canvas->Pixels[i][j];
rgb[i][j].r_color=GetRvalue(color);
rgb[i][j].g_color=GetGvalue(color);
rgb[i][j].b_color=GetBvalue(color);
}
bitmap=new Graphics::TBitmap;
bitmap- >Width=width;
bitmap- >Height=height;
}
}
二、图像的柔化处理
柔化就是对图像进行平滑处理,减少相邻像素间的颜色差别,一般选用3*3像素块,将中间的像素值改成这9个像素的平均像素值,从而达到柔化效果。其代码如下:
void __fastcall TForm1::btnSmoothClick
(TObject *Sender)
int red,green,blue;
for(i=1;i< width-2;i++)
for(j=1;j< height-2;j++)
{ red=rgb[i-1][j-1].r_color+rgb[i][j-1].r
_color+rgb[i+1][j-1].r_color+
rgb[i-1][j].r_color+rgb[i][j].r
_color+rgb[i+1][j].r_color+
rgb[i-1][j+1].r_color+rgb[i][j+1].r
_color+rgb[i+1][j+1].r_color;
green=rgb[i-1][j-1].g_color+rgb[i][j-1].g
_color+rgb[i+1][j-1].g_color+
rgb[i-1][j].g_color+rgb[i][j].g
_color+rgb[i+1][j].g_color+
rgb[i-1][j+1].g_color+rgb[i][j+1].g
_color+rgb[i+1][j+1].g_color;
blue=rgb[i-1][j-1].b_color+rgb[i][j-1].b
_color+rgb[i+1][j-1].b_color+
rgb[i-1][j].b_color+rgb[i][j].b
_color+rgb[i+1][j].b_color +
rgb[i-1][j+1].b_color+rgb[i][j+1].b
_color+rgb[i+1][j+1].b_color;
bitmap- >Canvas- >Pixels[i][j]
=RGB(red/9,green/9,blue/9);
}
Image1- >Picture- >Bitmap- >Assign(bitmap);
}
三、图像的锐化处理
图像的锐化处理正好与柔化处理相反,它的目的是突出图像的变化部分,这里采用的算法是将要处理的像素与它左对角线的像素之间的差值乘上一个锐化度数,然后再加上原先的像素值:new_value=original_value+degree*difference,你可以通过改变degree的值来调节锐化效果。这里需要注意的是得到的像素新值可能会超出颜色值的有效范围(0-255),所以程序要检验结果的有效性,为此需定义两个函数:
int min(int value1,int value2)
{ if(value1 >value2)return value2;
else return value1;
}int max(int value1,int value2)
{ if(value1 >value2)return value1;
else return value2;}
锐化处理的代码如下:
void __fastcall TForm1::btnSharpeClick
(TObject *Sender)
{
float degree=0.3;
int red,green,blue;
for(i=1;i< width-1;i++)
for(j=1;j< height-1;j++)
{ red=rgb[i][j].r_color+degree*(rgb[i][j].r
_color-rgb[i-1][j-1].r_color);
green=rgb[i][j].g_color+degree*(rgb[i][j].g
_color-rgb[i-1][j-1].g_color);
blue=rgb[i][j].b_color+degree*(rgb[i][j].b
_color-rgb[i-1][j-1].b_color);
red=min(255,max(0,red));
green=min(255,max(0,green));
blue=min(255,max(0,blue));
bitmap- >Canvas->Pixels[i][j]=RGB (red,green,blue);
} Image1- >Picture- >Bitmap- >Assign(bitmap);
}
四、图像的浮雕效果实现
浮雕效果就是只将图像的变化部分突出出来,而相同颜色部分则被淡化,使图像出现纵深感,从而达到浮雕效果,这里采用的算法是将要处理的像素取值为与处于对角线上的另一个像素间的差值,这样只有颜色变化区才会出现色彩,而颜色平淡区因差值几乎为零则变成黑色,你可以通过加上一个常量来增加一些亮度:new_value=difference+const_value,具体代码如下:
void __fastcall TForm1::btnEmbossClick
(TObject *Sender)
{ int red,green,blue;
const int const_value=128;
for(i=0;i< width-2;i++)
for(j=0;j< height-2;j++)
{ red=abs(rgb[i][j].r_color-rgb[i+1][j+1].r
_color+const_value);
}
green=abs(rgb[i][j].g_color-rgb[i+1][j+1].g
_color+const_value);
blue=abs(rgb[i][j].b_color-rgb[i+1][j+1].b_
color+const_value);
bitmap- >Canvas- >Pixels[i][j]=RGB
(red,green,blue);
}
Image1- >Picture- >Bitmap- >Assign(bitmap);
}
上面介绍了图像处理中的几个常见操作,所采用的算法相对比较简单,感兴趣的朋友可以举一返三,通过改进上述算法,达到更好的特殊效果。以上代码在C++ Builder3、Pwin98下编译、运行通过。
最新更新
Objective-C语法之代码块(block)的使用
VB.NET eBook
Add-in and Automation Development In VB.NET 2003 (F
Add-in and Automation Development In VB.NET 2003 (8
Add-in and Automation Development in VB.NET 2003 (6
Add-in and Automation Development In VB.NET 2003 (5
AddIn Automation Development In VB.NET 2003 (4)
AddIn And Automation Development In VB.NET 2003 (2)
Addin and Automation Development In VB.NET 2003 (3)
AddIn And Automation Development In VB.NET 2003 (1)
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
武装你的WEBAPI-OData入门
武装你的WEBAPI-OData便捷查询
武装你的WEBAPI-OData分页查询
武装你的WEBAPI-OData资源更新Delta
5. 武装你的WEBAPI-OData使用Endpoint 05-09
武装你的WEBAPI-OData之API版本管理
武装你的WEBAPI-OData常见问题
武装你的WEBAPI-OData聚合查询
OData WebAPI实践-OData与EDM
OData WebAPI实践-Non-EDM模式