将绘制的图像修改为圆角矩形

Modifying drawn image as a rounded rectangle

按照代码 我正在尝试弯曲矩形的边缘,使其不全是正方形。

现在的示例:

以及我希望它做什么:

使用此代码:

Using br As New SolidBrush(solidBGColor)
   Dim r As New RectangleF(0, 0, myPictureBox.Width, myPictureBox.Height)
   Dim gp As New System.Drawing.Drawing2D.GraphicsPath()
   Dim d As Integer = 5

   gp.AddArc(r.X, r.Y, imgSizeWH(0), imgSizeWH(1), 180, 90)
   gp.AddArc(r.X + r.Width - d, r.Y, imgSizeWH(0), imgSizeWH(1), 270, 90)
   gp.AddArc(r.X + r.Width - d, r.Y + r.Height - d, imgSizeWH(0), imgSizeWH(1), 0, 90)
   gp.AddArc(r.X, r.Y + r.Height - d, imgSizeWH(0), imgSizeWH(1), 90, 90)

   g.FillPath(br, gp)
End Using

我有一张图片似乎不正确:

完整代码:

Private Function CreateLabeledAvatar(av As Image, text As String) As Image
    Dim imgSizeWH() As Integer = {800, 800}
    Dim bmp As New Bitmap(imgSizeWH(0), imgSizeWH(1))
    Dim solidBGColor As Color = DirectCast(New ColorConverter().ConvertFromString("#" + _BackgroundColours(New Random().[Next](0, _BackgroundColours.Count - 1))), Color)

    Using g As Graphics = Graphics.FromImage(bmp)
        Using br As New SolidBrush(solidBGColor)
            Dim r As New RectangleF(0, 0, myPictureBox.Width, myPictureBox.Height)
            Dim gp As New System.Drawing.Drawing2D.GraphicsPath()
            Dim d As Integer = 5

            gp.AddArc(r.X, r.Y, imgSizeWH(0), imgSizeWH(1), 180, 90)
            gp.AddArc(r.X + r.Width - d, r.Y, imgSizeWH(0), imgSizeWH(1), 270, 90)
            gp.AddArc(r.X + r.Width - d, r.Y + r.Height - d, imgSizeWH(0), imgSizeWH(1), 0, 90)
            gp.AddArc(r.X, r.Y + r.Height - d, imgSizeWH(0), imgSizeWH(1), 90, 90)

            g.FillPath(br, gp)
            'g.FillRectangle(br, 0, 0, bmp.Width, bmp.Height)
        End Using

        g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
        g.CompositingQuality = CompositingQuality.HighQuality
        g.TextRenderingHint = TextRenderingHint.AntiAlias
        g.SmoothingMode = SmoothingMode.HighQuality
        g.DrawImage(av, 0, 0, bmp.Width, bmp.Height)

        Using fnt As New Font("Arial", 132, FontStyle.Bold, GraphicsUnit.Pixel)
            TextRenderer.DrawText(g, text, fnt, New Rectangle(0, 0, imgSizeWH(0), imgSizeWH(1)),
                  Color.WhiteSmoke, TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter)
        End Using
    End Using

    Return bmp
End Function

您的 GraphicsPath 只是一些圆弧,没有线条使其成为真正的圆角矩形。如果尺寸是 800x800,您可能需要更大的 d(直径);并且由于您正在处理图像,因此您应该使用图像大小而不是 PictureBox 的大小(这可能是圆比图像大的原因)。将其用于 GP 块:

' use the actual size, not those array values
Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)

Using gp As New GraphicsPath
    ' arc radius is specified, but we use it as diameter
    Dim d As Int32 = radius * 2

    gp.StartFigure()
    ' top left
    ' LRTB creates a temp rect rather than calculating Size
    '   complete with typos and miscalcs
    gp.AddArc(Rectangle.FromLTRB(rect.Left, rect.Top,
                             rect.Left + d, rect.Top + d), 180, 90)
    gp.AddLine(rect.Left + d, rect.Top, rect.Right - d, rect.Top)

    ' top right
    gp.AddArc(Rectangle.FromLTRB(rect.Right - d, rect.Top,
                            rect.Right, rect.Top + d), -90, 90)
    gp.AddLine(rect.Right, rect.Top + d, rect.Right, rect.Bottom - d)

    ' bottom right
    gp.AddArc(Rectangle.FromLTRB(rect.Right - d, rect.Bottom - d,
                            rect.Right, rect.Bottom), 0, 90)
    gp.AddLine(rect.Right - d, rect.Bottom, rect.Left + d, rect.Bottom)

    ' bottom left
    gp.AddArc(Rectangle.FromLTRB(rect.Left, rect.Bottom - d,
                            rect.Left + d, rect.Bottom), 90, 90)
    gp.AddLine(rect.Left, rect.Bottom - d, rect.Left, rect.Top + d)

    gp.CloseFigure()
    Using p As New Pen(BackColor), br = New SolidBrush(BackColor)
        g.DrawPath(p, gp)
        g.FillPath(br, gp)
    End Using
End Using

请注意,在较小的图像上尝试此操作时,它可以帮助创建更大的图像,例如最终尺寸的 2、4 或 8 倍,绘制圆角矩形(使用半径 * {2、4 或 8 }) 然后缩小结果。这使得角落更好。1

使用 250x250 图像和 42 半径的结果:

Picturebox 有一个固定的边框并且在面板上(淡黄色),以证明透明度和边缘。使用较小的直径进行较小的切割。此外,为了获得最大的灵活性,我的 class 允许指定所有这些硬编码的字体、大小和颜色参数——图像显示用于文本颜色的 MistyRose。

1 超大有助于小图像 锐化曲线。我的 250 图像有一个非常小的曲线 (Radius == 8 ) 看起来有点糟糕。