#include <cv.h>
#include <cvcam.h>
#include <cxcore.h>
#include <highgui.h>
#include <stdio.h>
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cvcam.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")
#define SHAPE_NONE 0
#define SHAPE_LINE 1
#define SHAPE_RECT 2
#define SHAPE_CIRCLE 3
#define SHAPE_ESLIPSE 4
#define SHAPE_PLYGON 5
#define SHAPE_ERASER 6
//用来记录在全局范围内用户要画的图像类型
int g_ShapeStyle;
//画直线所需要的两个点
CvPoint g_StartPoint;
CvPoint g_EndPoint;
//画矩形椭圆所需要的CRect类型变量
CvRect g_rect;
//确定当前程序是否处于画图状态
bool g_IsDraw=false;
//用来将图像还原
void ResetImage(IplImage *src_image,IplImage *dst_image);
//在图像上画直线
void DrawLine(IplImage *image,CvPoint startpoint,CvPoint endpoint);
//在图像上画矩形
void DrawRect(IplImage *image,CvRect rect);
//在图像上画一个简易的椭圆
void DrawEllipse(IplImage *image,CvRect rect);
//在图像上画一个圆形
void DrawCircle(IplImage *image,CvRect rect);
//类型橡皮擦的功能
void EraseImage(IplImage *image,CvPoint startpoint,CvPoint endpoint);
//鼠标事件的回调函数
void my_callback(int event, int x, int y, int flags, void* param);
void main()
{
printf("…………………………………………(N)创建一个图像/n/n");
printf("…………………………………………(L)画线/n/n");
printf("…………………………………………(S)画方/n/n");
printf("…………………………………………(C)画圆/n/n");
printf("…………………………………………(E)画椭圆/n/n");
printf("…………………………………………(P)画多边形/n/n");
printf("…………………………………………(R)橡皮擦/n/n");
//载入图像
IplImage *image=cvCreateImage(cvSize(500,500),IPL_DEPTH_8U,3);
assert(image!=NULL);
//临时图像
IplImage *temp_image=cvCloneImage(image);
//创建窗口
cvNamedWindow("Show");
cvShowImage("Show",image);
//创建窗口回调函数
cvSetMouseCallback("Show",my_callback,temp_image);
//用来记录用户所输入的字符型变量
char select='n';
while (1)
{
switch (select)
{
case 'n':
//新建图像
g_ShapeStyle=SHAPE_LINE;
ResetImage(image,temp_image);
printf("新建图像/n/n");
break;
//画直线
case 'l':
g_ShapeStyle=SHAPE_LINE;
break;
// 画方形
case 's':
g_ShapeStyle=SHAPE_RECT;
break;
//画椭圆
case 'e':
g_ShapeStyle=SHAPE_ESLIPSE;
break;
//画圆
case 'c':
g_ShapeStyle=SHAPE_CIRCLE;
break;
case 'r':
g_ShapeStyle=SHAPE_ERASER;
break;
//画多边形
case 'p':
g_ShapeStyle=SHAPE_PLYGON ;
break;
case 27:
return ;
}
cvShowImage("Show",temp_image);
select=cvWaitKey(30);
}
}
//Show窗口的回调函数
void my_callback(int event, int x, int y, int flags, void* param)
{
IplImage *image=(IplImage*)(param);
switch (event)
{
//当鼠标左键被按下
case CV_EVENT_LBUTTONDOWN:
{
//如果是画线
if (SHAPE_LINE==g_ShapeStyle || SHAPE_ERASER==g_ShapeStyle)
{
g_IsDraw=true;
g_StartPoint.x=x;
g_StartPoint.y=y;
}
//如果是画矩形|椭圆|圆
if (SHAPE_RECT==g_ShapeStyle ||SHAPE_ESLIPSE==g_ShapeStyle ||SHAPE_CIRCLE==g_ShapeStyle)
{
g_IsDraw=true;
g_rect.x=x;
g_rect.y=y;
g_rect.width=0;
g_rect.height=0;
}
}
break;
//当鼠标左键在移动过程中
case CV_EVENT_MOUSEMOVE:
{
//如果是画线
if (SHAPE_LINE==g_ShapeStyle||SHAPE_ERASER==g_ShapeStyle)
{
if (true==g_IsDraw)
{
g_EndPoint.x=x;
g_EndPoint.y=y;
}
}
//如果是画矩形|椭圆|圆
if (SHAPE_RECT==g_ShapeStyle ||SHAPE_ESLIPSE==g_ShapeStyle ||SHAPE_CIRCLE==g_ShapeStyle)
{
if (true==g_IsDraw)
{
g_rect.width=x-g_rect.x;
g_rect.height=y-g_rect.y;
}
}
break;
}
//当鼠标左键被释放后
case CV_EVENT_LBUTTONUP:
{
//如果是画线
if (SHAPE_LINE==g_ShapeStyle)
{
g_IsDraw=false;
DrawLine(image,g_StartPoint,g_EndPoint);
}
//如果是画矩形
if (SHAPE_RECT==g_ShapeStyle)
{
g_IsDraw=false;
if (g_rect.width<0)
{
g_rect.x+=g_rect.width;
g_rect.width*=-1;
}
if (g_rect.height<0)
{
g_rect.y+=g_rect.height;
g_rect.height*=-1;
}
DrawRect(image,g_rect);
}
//如果是画椭圆形
if (SHAPE_ESLIPSE==g_ShapeStyle)
{
g_IsDraw=false;
if (g_rect.width<0)
{
g_rect.x+=g_rect.width;
g_rect.width*=-1;
}
if (g_rect.height<0)
{
g_rect.y+=g_rect.height;
g_rect.height*=-1;
}
DrawEllipse(image,g_rect);
}
//如果是画圆
if (SHAPE_CIRCLE==g_ShapeStyle)
{
g_IsDraw=false;
if (g_rect.width<0)
{
g_rect.x+=g_rect.width;
g_rect.width*=-1;
}
if (g_rect.height<0)
{
g_rect.y+=g_rect.height;
g_rect.height*=-1;
}
DrawCircle(image,g_rect);
}
//如果是橡皮擦
if (SHAPE_ERASER==g_ShapeStyle)
{
g_IsDraw=false;
EraseImage(image,g_StartPoint,g_EndPoint);
}
}
break;
}
}
//还原图像
void ResetImage(IplImage *src_image,IplImage *dst_image)
{
cvCopyImage(src_image,dst_image);
}
//在图像上画直线
void DrawLine(IplImage *image,CvPoint startpoint,CvPoint endpoint)
{
assert(image!=NULL);
cvDrawLine(
image,
startpoint,
endpoint,
CV_RGB(255,0,0),
1
);
}
//在图像上画方
void DrawRect(IplImage *image,CvRect rect)
{
assert(image!=NULL);
cvRectangle(
image,
cvPoint(rect.x,rect.y),
cvPoint(rect.x+rect.width,rect.y+rect.height),
CV_RGB(255,0,0),
1
);
}
//在图像上画椭圆
void DrawEllipse(IplImage *image,CvRect rect)
{
assert(image!=NULL);
//获得所属矩形大小
CvSize size=cvSize(rect.width/2,rect.height/2);
//获得矩形的中心点
CvPoint center=cvPoint((rect.x+rect.width)/2,(rect.y+rect.height)/2);
//角度
double angle=0;
//起点夹角
double start_angle=0;
//终点夹角
double end_angle=360;
cvEllipse(image,center,size,angle,start_angle,end_angle,CV_RGB(255,0,0));
}
//在图像上画一个圆
void DrawCircle(IplImage *image,CvRect rect)
{
assert(image!=NULL);
if (rect.width!=rect.height)
{
rect.width=rect.height;
}
//圆的半径
int radis=rect.height/2;
CvPoint center=cvPoint((rect.x+rect.width)/2,(rect.y+rect.height)/2);
cvCircle(image,center,radis,CV_RGB(255,0,0),1);
}
//用黑色画笔实现貌似橡皮擦的功能
void EraseImage(IplImage *image,CvPoint startpoint,CvPoint endpoint)
{
assert(image!=NULL);
cvDrawLine(
image,
startpoint,
endpoint,
CV_RGB(0,0,0),
20
);
}