voici un code permettant de tracer une ligne ou un cercle avec un anticrènelage
il vous suffit de mettre ça dans un module et d'appeller les fonctions DrawLineAA, DrawCircleAA (DrawLine et DrawCircle servent à la même chose sans anticrènelage et SetPixelAA c'est ce qui trace un pixel avec un antialias en fonction de ce qu'il y a après la virgule)
DeviceContext c'est le .hDC de l'objet sur lequel vous voulez tracer (par exemple Form1.hDC ou Picture1.hDC)
le ScaleMode de l'objet sur lequel on trace doit être sur 3 (vbPixel)
les autres paramètres sont assez explicites pour ne pas être commentés.
notez qu'avec SetPixelAA vous pouvez faire un code qui trace par exemple une élipse ou un triangle et au lieu de faire SetPixel vous remplaces par SetPixelAA en mettant des paramètres de type Double donc avec une virgule donc avec un anticrènelage :) et vous obtiendrez un superbe anticrènelage.
Source / Exemple :
' ======================================
' DECLARATIONS D'API
' ======================================
Private Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetPixelV Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long
' ======================================
' AVEC ANTICRENELAGE
' ======================================
' trace un pixel avec un anticrènelage
Public Sub SetPixelAA( _
ByVal DeviceContext As Long, _
ByVal XX As Single, _
ByVal YY As Single, _
ByVal r As Byte, _
ByVal g As Byte, _
ByVal b As Byte)
Dim BackR As Byte
Dim BackG As Byte
Dim BackB As Byte
Dim BackCol As Long
Dim xi As Long: xi = CLng(XX)
Dim yi As Long: yi = CLng(YY)
Dim xp As Single
Dim yp As Single
Dim pa As Single
Dim pb As Single
Dim pc As Single
Dim pd As Single
If xi > XX Then xi = xi - 1
If yi > YY Then yi = yi - 1
If xi <> XX And yi <> YY Then
xp = XX - xi
yp = YY - yi
pa = (1 - xp) * (1 - yp)
pb = xp * (1 - yp)
pc = (1 - xp) * yp
pd = xp * yp
BackCol = GetPixel(DeviceContext, xi, yi)
BackR = BackCol And &HFF
BackG = (BackCol \ &H100) And &HFF
BackB = (BackCol \ &H10000) And &HFF
SetPixelV DeviceContext, xi, yi, RGB(r * pa + BackR * (1 - pa), g * pa + BackG * (1 - pa), b * pa + BackB * (1 - pa))
BackCol = GetPixel(DeviceContext, xi + 1, yi)
BackR = BackCol And &HFF
BackG = (BackCol \ &H100) And &HFF
BackB = (BackCol \ &H10000) And &HFF
SetPixelV DeviceContext, xi + 1, yi, RGB(r * pb + BackR * (1 - pb), g * pb + BackG * (1 - pb), b * pb + BackB * (1 - pb))
BackCol = GetPixel(DeviceContext, xi, yi + 1)
BackR = BackCol And &HFF
BackG = (BackCol \ &H100) And &HFF
BackB = (BackCol \ &H10000) And &HFF
SetPixelV DeviceContext, xi, yi + 1, RGB(r * pc + BackR * (1 - pc), g * pc + BackG * (1 - pc), b * pc + BackB * (1 - pc))
BackCol = GetPixel(DeviceContext, xi + 1, yi + 1)
BackR = BackCol And &HFF
BackG = (BackCol \ &H100) And &HFF
BackB = (BackCol \ &H10000) And &HFF
SetPixelV DeviceContext, xi + 1, yi + 1, RGB(r * pd + BackR * (1 - pd), g * pd + BackG * (1 - pd), b * pd + BackB * (1 - pd))
ElseIf xi <> XX Then
pc = XX - xi
pa = 1 - (XX - xi)
BackCol = GetPixel(DeviceContext, xi, yi)
BackR = BackCol And &HFF
BackG = (BackCol \ &H100) And &HFF
BackB = (BackCol \ &H10000) And &HFF
SetPixelV DeviceContext, xi, yi, RGB(r * pa + BackR * (1 - pa), g * pa + BackG * (1 - pa), b * pa + BackB * (1 - pa))
BackCol = GetPixel(DeviceContext, xi + 1, yi)
BackR = BackCol And &HFF
BackG = (BackCol \ &H100) And &HFF
BackB = (BackCol \ &H10000) And &HFF
SetPixelV DeviceContext, xi + 1, yi, RGB(r * pc + BackR * (1 - pc), g * pc + BackG * (1 - pc), b * pc + BackB * (1 - pc))
ElseIf yi <> YY Then
pb = YY - yi
pa = 1 - (YY - yi)
BackCol = GetPixel(DeviceContext, xi, yi)
BackR = BackCol And &HFF
BackG = (BackCol \ &H100) And &HFF
BackB = (BackCol \ &H10000) And &HFF
SetPixelV DeviceContext, xi, yi, RGB(r * pa + BackR * (1 - pa), g * pa + BackG * (1 - pa), b * pa + BackB * (1 - pa))
BackCol = GetPixel(DeviceContext, xi, yi + 1)
BackR = BackCol And &HFF
BackG = (BackCol \ &H100) And &HFF
BackB = (BackCol \ &H10000) And &HFF
SetPixelV DeviceContext, xi, yi + 1, RGB(r * pb + BackR * (1 - pb), g * pb + BackG * (1 - pb), b * pb + BackB * (1 - pb))
Else
SetPixelV DeviceContext, XX, YY, RGB(r, g, b)
End If
End Sub
' trace une ligne avec anticrènelage
Public Sub DrawLineAA( _
ByVal DeviceContext As Long, _
ByVal x1 As Single, _
ByVal y1 As Single, _
ByVal x2 As Single, _
ByVal y2 As Single, _
ByVal Color As Long)
Dim m As Single
Dim b As Single
Dim XX As Single
Dim YY As Single
Dim rr As Byte: rr = Color And &HFF
Dim gg As Byte: gg = (Color \ &H100) And &HFF
Dim bb As Byte: bb = (Color \ &H10000) And &HFF
If x2 = x1 Then
m = (y2 - y1) / 1
Else
m = (y2 - y1) / (x2 - x1)
End If
b = y1 - (m * x1)
If Abs(m) <= 1 Then
If x1 <= x2 Then
For XX = x1 To x2 - 1
YY = m * XX + b
SetPixelAA DeviceContext, XX, YY, rr, gg, bb
Next XX
Else
For XX = x2 + 1 To x1
YY = m * XX + b
SetPixelAA DeviceContext, XX, YY, rr, gg, bb
Next XX
End If
Else
If y1 <= y2 Then
For YY = y1 To y2 - 1
XX = (YY - b) / m
SetPixelAA DeviceContext, XX, YY, rr, gg, bb
Next YY
Else
For YY = y2 + 1 To y1
XX = (YY - b) / m
SetPixelAA DeviceContext, XX, YY, rr, gg, bb
Next YY
End If
End If
End Sub
' trace un cercle avec anticrènelage
Public Sub DrawCircleAA( _
ByVal DeviceContext As Long, _
ByVal X As Single, _
ByVal Y As Single, _
ByVal Rayon As Single, _
ByVal Color As Long)
Dim XX As Single
Dim YY As Single
Dim rr As Byte: rr = Color And &HFF
Dim gg As Byte: gg = (Color \ &H100) And &HFF
Dim bb As Byte: bb = (Color \ &H10000) And &HFF
If Rayon = 0 Then Exit Sub
SetPixelAA DeviceContext, X + Rayon, Y, rr, gg, bb
SetPixelAA DeviceContext, X, Y + Rayon, rr, gg, bb
SetPixelAA DeviceContext, X, Y - Rayon, rr, gg, bb
SetPixelAA DeviceContext, X - Rayon, Y, rr, gg, bb
For XX = 1 To Rayon * 0.71 ' = 1 / Sqr(2)
YY = Sqr(Rayon * Rayon - XX * XX)
SetPixelAA DeviceContext, XX + X, YY + Y, rr, gg, bb
SetPixelAA DeviceContext, -XX + X, YY + Y, rr, gg, bb
SetPixelAA DeviceContext, XX + X, -YY + Y, rr, gg, bb
SetPixelAA DeviceContext, -XX + X, -YY + Y, rr, gg, bb
SetPixelAA DeviceContext, YY + X, XX + Y, rr, gg, bb
SetPixelAA DeviceContext, -YY + X, XX + Y, rr, gg, bb
SetPixelAA DeviceContext, YY + X, -XX + Y, rr, gg, bb
SetPixelAA DeviceContext, -YY + X, -XX + Y, rr, gg, bb
Next XX
End Sub
' ======================================
' SANS ANTICRENELAGE
' ======================================
' trace une ligne
Public Sub DrawLine( _
ByVal DeviceContext As Long, _
ByVal x1 As Long, _
ByVal y1 As Long, _
ByVal x2 As Single, _
ByVal y2 As Single, _
ByVal Color As Long)
Dim m As Single
Dim b As Single
Dim XX As Long
Dim YY As Long
If x2 = x1 Then
m = (y2 - y1) / 1
Else
m = (y2 - y1) / (x2 - x1)
End If
b = y1 - (m * x1)
If Abs(m) <= 1 Then
If x1 <= x2 Then
For XX = x1 To x2 - 1
YY = m * XX + b
SetPixelV DeviceContext, XX, YY, Color
Next XX
Else
For XX = x2 + 1 To x1
YY = m * XX + b
SetPixelV DeviceContext, XX, YY, Color
Next XX
End If
Else
If y1 <= y2 Then
For YY = y1 To y2 - 1
XX = (YY - b) / m
SetPixelV DeviceContext, XX, YY, Color
Next YY
Else
For YY = y2 + 1 To y1
XX = (YY - b) / m
SetPixelV DeviceContext, XX, YY, Color
Next YY
End If
End If
End Sub
' trace un cercle
Public Sub DrawCircle( _
ByVal DeviceContext As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal Rayon As Long, _
ByVal Color As Long)
Dim XX As Long
Dim YY As Long
Dim rr As Byte: rr = Color And &HFF
Dim gg As Byte: gg = (Color \ &H100) And &HFF
Dim bb As Byte: bb = (Color \ &H10000) And &HFF
If Rayon = 0 Then Exit Sub
SetPixelV DeviceContext, X + Rayon, Y, Color
SetPixelV DeviceContext, X, Y + Rayon, Color
SetPixelV DeviceContext, X, Y - Rayon, Color
SetPixelV DeviceContext, X - Rayon, Y, Color
For XX = 1 To Rayon * 0.71 ' = 1 / Sqr(2)
YY = Sqr(Rayon * Rayon - XX * XX)
SetPixelV DeviceContext, XX + X, YY + Y, Color
SetPixelV DeviceContext, -XX + X, YY + Y, Color
SetPixelV DeviceContext, XX + X, -YY + Y, Color
SetPixelV DeviceContext, -XX + X, -YY + Y, Color
SetPixelV DeviceContext, YY + X, XX + Y, Color
SetPixelV DeviceContext, -YY + X, XX + Y, Color
SetPixelV DeviceContext, YY + X, -XX + Y, Color
SetPixelV DeviceContext, -YY + X, -XX + Y, Color
Next XX
End Sub
Conclusion :
14/09/2004 :
- j'ai corrigé la faute à "anticrènelage" selon l'académie française.
24/06/2004 :
- j'ai remplacé SetPixel par SetPixelV
- j'ai viré les Double que j'ai remplacé par des Long là ou il n'y avait pas lieu d'utiliser des Double.
- J'ai remplacé tous les Double par des Single qui sont plus rapides que les Doubles car moins précis (mais nous n'avons pas besoin de Double ici)
Merci à vlad2 ;)
22/06/2004
- J'ai modifié un peu le code dans SetPixelAA, en effet il y avait une erreur, maintenant c'est nickel !
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.