GDI+繪製圓角矩形
阿新 • • 發佈:2019-02-14
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));
結果: