2016-04-05 4 views
3

Следуя коду 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 

У меня есть образ, который только что сделал sn't кажется правильным:

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 

ответ

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}), то уменьшите результат. Это делает более приятными углы.

Результата используя 250x250 изображение и радиус 42:

enter image description here

PictureBox имеет фиксированную границу и находится на панели (желтоватая), чтобы доказательства прозрачности и края. Используйте меньший диаметр для небольших разрезов. Кроме того, для максимальной гибкости мой находится в классе, который позволяет указать все эти жестко заданные параметры Font, Size и Color - на изображении показано, что MistyRose используется для цвета текста.

Вспомогательные средства для мелких изображений или острые кривые. Мое изображение 250 с очень маленькой кривой (Radius == 8) выглядит неплохо.

+0

Это сделало трюк! Спасибо за вашу помощь, Плутоникс! – StealthRT

Смежные вопросы