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

时间:2016-04-05 19:46:24

标签: .net vb.net graphics system.drawing drawing2d

遵循代码here我试图弯曲矩形的边缘,使其不是全部正方形。

现在的样子:

enter image description here

我正在寻找它:

enter image description here

使用此代码:

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

我的图片似乎不正确:

enter image description here

完整代码:

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

1 个答案:

答案 0 :(得分:3)

你的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:

enter image description here

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

1 超大尺寸有助于小图像清晰的曲线。我的250图像具有非常小的曲线(半径== 8)看起来很糟糕。