1
What I need to do is a PictureBox
that has rounded corners, but the problem is that I can’t make them round without serrations.
One of the ways I found it was by using the property Region
:
Private Function GetRoundedRect(ByVal retangulo As RectangleF, ByVal raio As Single) As GraphicsPath
' Se o raio do arco for maior ou igual à metada da largura ou altura do retângulo
' retorna um objeto no formato de capsula.
If raio >= (Math.Min(retangulo.Width, retangulo.Height) / 2.0) Then
Return GetCapsule(retangulo)
End If
Dim diametro As Single = raio + raio
Dim arcRect As New RectangleF(retangulo.Location, New SizeF(diametro, diametro))
Dim gp As New GraphicsPath()
' Arco superior esquerdo.
gp.AddArc(arcRect, 180, 90)
' Arco superior direito.
arcRect.X = retangulo.Right - diametro
gp.AddArc(arcRect, 270, 90)
' Arco inferior direito.
arcRect.Y = retangulo.Bottom - diametro
gp.AddArc(arcRect, 0, 90)
' Arco inferior esquerdo
arcRect.X = retangulo.Left
gp.AddArc(arcRect, 90, 90)
gp.CloseFigure()
Return gp
End Function
Private Function GetCapsule(ByVal retangulo As RectangleF) As GraphicsPath
Dim diametro As Single
Dim arcRect As RectangleF
Dim gp As New GraphicsPath()
Try
If retangulo.Width > retangulo.Height Then
' Capsula horizontal
diametro = retangulo.Height
arcRect = New RectangleF(retangulo.Location, New SizeF(diametro, diametro))
gp.AddArc(arcRect, 90, 180)
arcRect.X = retangulo.Right - diametro
gp.AddArc(arcRect, 270, 180)
ElseIf retangulo.Height > retangulo.Width Then
' Capsula horizontal
diametro = retangulo.Width
arcRect = New RectangleF(retangulo.Location, New SizeF(diametro, diametro))
gp.AddArc(arcRect, 180, 180)
arcRect.Y = retangulo.Bottom - diametro
gp.AddArc(arcRect, 0, 180)
Else
' Circulo
gp.AddEllipse(retangulo)
End If
Catch e As Exception
gp.AddEllipse(retangulo)
Finally
gp.CloseFigure()
End Try
Return gp
End Function
How I used:
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Me.Region = New System.Drawing.Region(GetRoundedRect(New RectangleF(0, 0, Width, Height), 20))
MyBase.OnPaint(e)
End Sub
This works, but generates serrated corners:
So I thought I’d do the same thing using the Graphics
. What I tried to do was delimit the area where the image would appear leaving the rest with the color of Background
of the control where the Picturebox
was.
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
' Qualidade
e.Graphics.CompositingQuality = CompositingQuality.HighQuality
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.CompositingMode = CompositingMode.SourceOver
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear
Dim Fonte As Bitmap = ImaList(0)
Dim f As GraphicsPath = GetRoundedRect(New RectangleF(0, 0, PictureBox1.Width, PictureBox1.Height), 20)
Dim borderPen As New Pen(PictureBox1.Parent.BackColor, 1) With {
.Alignment = PenAlignment.Outset
}
' Cria limite para área do desenho
e.Graphics.Clip = New Region(f)
' Desenha a imagem
e.Graphics.DrawImage(Fonte, 0, 0, PictureBox1.Width, PictureBox1.Height)
'Aplica uma bordar para nao ficar serrilhado
e.Graphics.DrawPath(borderPen, f)
End Sub
The result is good, it no longer gets the serrated, but when trying to put a label
same as the previous image it looks the same as the bottom of the image.
So what I wanted to know is how can I leave the rounded edges without serration, taking into account the controls that are inside it? Just remembering that the label
has an animation of going up and down, so I need events to work normally.
SmoothingMode
does not work if you use theRegion
, when I add a child control gets serrated. The other 2 give good results, but I still have the problem that when I add a child control, it always sits on the round edges. I solved this problem by painting the child control, but I can’t add the "edges" in the child control (when I add for example a black line around the parent control I can not draw in the child control, to look like the father, since I could not leave the "painting" over the child control.– Lucas Pedro