You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GDI+绘制仅圆角抗锯齿的填充圆角矩形

绘制带抗锯齿圆角的填充矩形(仅圆角抗锯齿,侧边清晰)

我尝试绘制带有抗锯齿圆角的填充圆角矩形,但当前实现会让整个矩形都被抗锯齿处理,导致矩形侧边模糊。我希望仅让圆角部分抗锯齿,同时保持矩形侧边边缘清晰。

效果对比图

下方代码生成了仅线条和仅填充的效果,但如何实现最右侧手动用MS Paint制作的预期效果?

void GetRoundRectPath2(GraphicsPath* pPath, Rect r, int dia)
{
    // 直径不能超过矩形的宽或高
    if (dia > r.Width)    dia = r.Width;
    if (dia > r.Height)    dia = r.Height;

    // 定义圆角区域
    Rect Corner(r.X, r.Y, dia, dia);

    // 重置路径
    pPath->Reset();

    // 左上角圆角
    pPath->AddArc(Corner, 180, 90);

    // 针对半径10(直径20)的微调
    if (dia == 20)
    {
        Corner.Width += 1;
        Corner.Height += 1;
        r.Width -= 1; r.Height -= 1;
    }

    // 右上角圆角
    Corner.X += (r.Width - dia - 1);
    pPath->AddArc(Corner, 270, 90);

    // 右下角圆角
    Corner.Y += (r.Height - dia - 1);
    pPath->AddArc(Corner, 0, 90);

    // 左下角圆角
    Corner.X -= (r.Width - dia - 1);
    pPath->AddArc(Corner, 90, 90);

    // 闭合路径
    pPath->CloseFigure();
}

void FillRoundRect2(Graphics* pGraphics, Brush* pBrush, Rect r, Color border, int radius)
{
    int dia = 2 * radius;

    // 设置为像素单位
    int oldPageUnit = pGraphics->SetPageUnit(UnitPixel);

    // 定义画笔
    Pen pen(border, 1);
    pen.SetAlignment(PenAlignmentCenter);

    // 创建路径对象
    GraphicsPath path;

    // 获取圆角矩形路径
    GetRoundRectPath2(&path, r, dia);

    // 填充路径
    pGraphics->FillPath(pBrush, &path);

    // 最后绘制边框,确保边框在顶层
    pGraphics->DrawPath(&pen, &path);

    // 恢复原页面单位
    pGraphics->SetPageUnit((Unit)oldPageUnit);
}

Graphics graphics(dc);
graphics.SetSmoothingMode(SmoothingModeAntiAlias);

// 仅绘制边框
SolidBrush sbrA(Gdiplus::Color(0,255,0,0)); // 完全透明
FillRoundRect2(&graphics, &sbrA, Gdiplus::Rect(10, 10, 40, 40), Gdiplus::Color(50, 255, 0, 0), 5);

// 仅填充区域
SolidBrush sbr(Gdiplus::Color(50, 255, 0, 0));
FillRoundRect2(&graphics, &sbr, Gdiplus::Rect(10, 10, 40, 40), Gdiplus::Color(0, 255, 0, 0), 5);

更新:
我找到一种效果较好的实现方法:先使用SetClip创建与目标圆角矩形尺寸完全一致的裁剪区域,再将传入FillRoundRect2的坐标向左、向上偏移1单位,宽高各增加2单位,使抗锯齿边缘落在绘制区域外。

Region myRegion(Rect(10, 10, 40, 40));
graphics.SetClip(&myRegion, CombineModeReplace);

SolidBrush sbr(Gdiplus::Color(50, 255, 0, 0));
FillRoundRect2(&graphics, &sbr, Gdiplus::Rect(10-1, 10-1, 40+2, 40+2), Gdiplus::Color(0, 255, 0, 0), 7);

优化后效果

内容的提问来源于stack exchange,提问作者user20716902

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 09:35:00