1. 程式人生 > >GDI+繪製圓角矩形

GDI+繪製圓角矩形

1、最近,用到GDI+繪圖,但是發現沒有繪製圓角矩形的函式,故自己寫了一個。下面貼出原理和程式碼,以作備份。

2、要繪製圓角矩形,基礎是普通的直角矩形,需要做的就是將直角畫成弧形。

3、繪製圓角矩形可以由兩個部分組成:第一部分是繪製四個圓角(左上、右上、右下、左下);第二部分是用直線連線四個圓角。

4、繪製第一部分用到Graphics.DrawArc 方法:

本例用到的是下面這個過載函式:

Graphics.DrawArc 方法 (Pen, Single, Single, Single, Single, Single, Single)

定義如下:

public:
void DrawArc(
	Pen^ pen, 
	float x, 
	float y, 
	float width, 
	float height, 
	float startAngle, 
	float sweepAngle
)
引數說明:
引數
pen
Pen,它確定弧線的顏色、寬度和樣式。
x
定義橢圓的矩形的左上角的 x 座標。
y
定義橢圓的矩形的左上角的 y 座標。
width
定義橢圓的矩形的寬度。
height
定義橢圓的矩形的高度。
startAngle
從 x 軸到弧線的起始點沿順時針方向度量的角(以度為單位)。
sweepAngle
從 startAngle 引數到弧線的結束點沿順時針方向度量的角(以度為單位)。



5、第二部分用到Graphics.DrawLine 方法:

本例用到的是下面這個過載函式:

Graphics.DrawLine 方法 (Pen, Single, Single, Single, Single)

定義如下:

public:
void DrawLine (
	Pen^ pen, 
	float x1, 
	float y1, 
	float x2, 
	float y2
)
引數說明:
引數
pen
Pen,它確定線條的顏色、寬度和樣式。
x1
第一個點的 x 座標。
y1
第一個點的 y 座標。
x2
第二個點的 x 座標。
y2
第二個點的 y 座標。


6、具體繪製,先看一張圖:



說明:

首先,大矩形即是我們要畫的矩形(圖中是直角的,要將其畫成圓角),大矩形的4個角上各有一個小矩形,這4個小矩形即是用來畫圓角的。

其次,用DrawArc畫圓角,因為矩形相鄰兩邊是垂直的,所以繪製的圓弧必須是90度的,也就是引數sweepAngle必須是90度

再次,圖中標出的4個紅點的座標即是DrawArc函式定義橢圓的矩形的左上角的座標。

由上可知,繪製圓角矩形需要幾個值:

一是矩形左上角的座標,即圖中的(x,y);

二是4個紅點的座標。

三是藍點的座標(用於畫連線圓角的直線,即矩形的邊)。

7、具體程式碼:

函式宣告:

//////////////////////////////////////////////////////////////////////////////////
	//------------------------------------ 繪製圓角矩形-------------------------------
	// 作者:Kaven
	// 建立時間:2014.07.08
	// 引數:
	//     pDC:     裝置環境
	//     x:        矩形的起點橫座標(即矩形左上角的橫座標x)
	//     y:        矩形的起點縱座標(即矩形左上角的縱座標y)
	//     Width:   矩形的寬度(halfWidth表示矩形寬度的一半)
	//     Height:  矩形的高度(halfHeight表示矩形高度的一半)
	//     arcSize:  調整圓角的弧度(0時弧度最大,為橢圓)
	//     lineColor:線條顏色
	//     lineWidth:線條寬度
	/////////////////////////////////////////////////////////////////////////////////
	void DrawRoundRectange(CDC* pDC, float x, float y, float Width, float Height, float arcSize, Color lineColor, float lineWidth);

函式定義:
// 繪製圓角矩形
void DrawRoundRectange(CDC* pDC, float x, float y, float Width, float Height, float arcSize, Color lineColor, float lineWidth)
{
	// 圓角矩形的半寬(hew)和半高(heh)
	float hew = Width/arcSize/2;
	float heh = Height/arcSize/2;

	// 圓角修正
	if(fabs(hew-heh)>10)
	{
		hew = heh = hew>heh ? heh : hew;
	}

	// 邊線修正
	int lineMove = 1;

	// 建立GDI+物件
	Graphics  g(pDC->GetSafeHdc());

	//設定畫圖時的濾波模式為消除鋸齒現象
	g.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);

	//建立畫筆
	Pen pen(lineColor, lineWidth);


	//////////////////////////////////////////////////////////////////////////
	// 畫圓角
	//////////////////////////////////////////////////////////////////////////
	// 畫左上圓角
	g.DrawArc(&pen, x, y, 2*hew, 2*heh, 180, 90);
	// 畫右上圓角
	g.DrawArc(&pen, x+Width-2*hew, y, 2*hew, 2*heh, 270, 90);
	// 畫右下圓角
	g.DrawArc(&pen, x+Width-2*hew, y+Height-2*heh, 2*hew, 2*heh, 0, 90);
	// 畫左下圓角
	g.DrawArc(&pen, x, y+Height-2*heh, 2*hew, 2*heh, 90, 90);

	//////////////////////////////////////////////////////////////////////////
	// 畫直線(連線4個圓角)
	//////////////////////////////////////////////////////////////////////////
	// 畫頂部橫線
	g.DrawLine(&pen, x+hew-lineMove, y, x+Width-hew+lineMove, y);
	// 畫右側豎線
	g.DrawLine(&pen, x+Width, y+heh-lineMove, x+Width, y+Height-heh+lineMove);
	// 畫底部橫線
	g.DrawLine(&pen, x+Width-hew+lineMove, y+Height, x+hew-lineMove, y+Height);
	// 畫左側豎線
	g.DrawLine(&pen, x, y+Height-heh+lineMove, x, y+heh-lineMove);
}



呼叫示例:
CDC *pDC = GetWindowDC();

DrawRoundRectange(pDC, 10, 100, 348, 60, 2, Color(255,0,0,0), 14);
DrawRoundRectange(pDC,100.2, 40.5, 45.4, 22.8, 6.34, Color(255,255,0,0), 2);
DrawRoundRectange(pDC, 35, 250, 60, 60, 2, Color(255,0,0,0), 4);
DrawRoundRectange(pDC, 400, 50, 60, 260, 2, Color(255,0,0,0), 3);

ReleaseDC(pDC);
結果:



注意:追加內容:

優化上述函式:

宣告:

        //////////////////////////////////////////////////////////////////////////////////
	//------------------------------------ 繪製圓角矩形-------------------------------
	// 作者:Kaven
	// 建立時間:2014.07.08
	// 引數:
	//     pDC:      裝置環境
	//     x:         矩形的起點橫座標(即矩形左上角的橫座標x)
	//     y:         矩形的起點縱座標(即矩形左上角的縱座標y)
	//     Width:    矩形的寬度(halfWidth表示矩形寬度的一半)
	//     Height:   矩形的高度(halfHeight表示矩形高度的一半)
	//     arcSize:   調整圓角的弧度(0時弧度最大,為橢圓)
	//     lineColor: 線條顏色
	//     lineWidth:線條寬度
	//     fillPath; 是否填充
	//     fillColor:填充顏色
	/////////////////////////////////////////////////////////////////////////////////
	void DrawRoundRectange(CDC* pDC, float x, float y, float Width, float Height, float arcSize, Color lineColor, float lineWidth, bool fillPath, Color fillColor);




定義:

// 繪製及填充圓角矩形
void DrawRoundRectange(CDC* pDC, float x, float y, float Width, float Height, float arcSize, Color lineColor, float lineWidth, bool fillPath, Color fillColor)
{
	// 小矩形的半寬(hew)和半高(heh)
	float hew = Width/arcSize/2;
	float heh = Height/arcSize/2;

	// 圓角修正
	if(fabs(hew-heh)>10)
	{
		hew = heh = hew>heh ? heh : hew;
	}

	// 建立GDI+物件
	Graphics  g(pDC->GetSafeHdc());

	//設定畫圖時的濾波模式為消除鋸齒現象
	g.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);


	// 繪圖路徑
	GraphicsPath roundRectPath;

	// 儲存繪圖路徑
	roundRectPath.AddLine(x+hew, y, x+Width-hew, y);  // 頂部橫線
	roundRectPath.AddArc(x+Width-2*hew, y, 2*hew, 2*heh, 270, 90); // 右上圓角

	roundRectPath.AddLine(x+Width, y+heh, x+Width, y+Height-heh);  // 右側豎線
	roundRectPath.AddArc(x+Width-2*hew, y+Height-2*heh, 2*hew, 2*heh, 0, 90); // 右下圓角

	roundRectPath.AddLine(x+Width-hew, y+Height, x+hew, y+Height);  // 底部橫線
	roundRectPath.AddArc(x, y+Height-2*heh, 2*hew, 2*heh, 90, 90); // 左下圓角

	roundRectPath.AddLine(x, y+Height-heh, x, y+heh);  // 左側豎線
	roundRectPath.AddArc(x, y, 2*hew, 2*heh, 180, 90); // 左上圓角

	//建立畫筆
	Pen pen(lineColor, lineWidth);

	// 繪製矩形
	g.DrawPath(&pen, &roundRectPath);

	// 是否填充
	if(!fillPath)
	{
		return;
	}
	else if(fillColor.GetAlpha() == 0)
	{
		fillColor = lineColor; // 若未指定填充色,則用線條色填充
	}

	// 建立畫刷
	SolidBrush brush(fillColor);

	// 填充
	g.FillPath(&brush, &roundRectPath);
}


呼叫示例:

DrawRoundRectange(pDC, 10, 100, 348, 60, 2, Color(255,0,0,0), 14, true , Color(255,255,255,0));
 		DrawRoundRectange(pDC, 10, 200, 348, 60, 4, Color(255,0,0,0), 4, true , Color(255,0,0,0));
 		DrawRoundRectange(pDC, 10.2, 40.5, 145.4, 22.8, 2.34, Color(255,255,0,0), 2, true, NULL);
		DrawRoundRectange(pDC, 210.2, 40.5, 145.4, 22.8, 2.34, Color(255,255,0,0), 2, true, Color(255,255,182,0));

結果: