Opération sur les Fonts
Opération sur les Fonts
Un projet que j'ai en tête depuis un long moment m'amène à me coltiner avec les FONTs et l'affichage graphique de texte.
Le but lointain est de parvenir rajouter une surcouche sur des images, permettant d'afficher le texte des bulles dans plusieurs langages, et de la façon la plus libre possible.
Il faut donc pouvoir manipuler l'affichage d'un texte, pour avoir au final performance / qualité / le moins de contrainte de mise en forme possible.
Or je suis très mécontent de la fonction DrawRotatedText(). Le résultat n'est pas constant, elle n'est pas souple, les fonctions TextWidth() et TextHeight() ne donnent pas les bonnes distances exactement.
Au fil de la mise en place de ce que j'ai en tête, je suis parvenu à dessiner un texte avec l'angle voulus pour n'importe quelle police.
Maintenant il reste les effets à mettre en place.
Donc, à votre avis, comment procéder pour obtenir le résultat suivant :
Ce qui m'intéresse c'est de pouvoir dessiner le contour d'un texte, quel qu'il soit (en fonction de la police chargée), avec une taille de font de 12 tout autant que pour du 80 !
Le but lointain est de parvenir rajouter une surcouche sur des images, permettant d'afficher le texte des bulles dans plusieurs langages, et de la façon la plus libre possible.
Il faut donc pouvoir manipuler l'affichage d'un texte, pour avoir au final performance / qualité / le moins de contrainte de mise en forme possible.
Or je suis très mécontent de la fonction DrawRotatedText(). Le résultat n'est pas constant, elle n'est pas souple, les fonctions TextWidth() et TextHeight() ne donnent pas les bonnes distances exactement.
Au fil de la mise en place de ce que j'ai en tête, je suis parvenu à dessiner un texte avec l'angle voulus pour n'importe quelle police.
Maintenant il reste les effets à mettre en place.
Donc, à votre avis, comment procéder pour obtenir le résultat suivant :
Ce qui m'intéresse c'est de pouvoir dessiner le contour d'un texte, quel qu'il soit (en fonction de la police chargée), avec une taille de font de 12 tout autant que pour du 80 !
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel )
Mon site : CeriseCode (Attention Chantier perpétuel )
Re: Opération sur les Fonts
Bonjour Graph100
peut être avec deux tailles de fonte
exemple: une fonte de 14 en noir et par-dessus une fonte de 12 blanche
ça devrait fonctionner et avoir une fonte de 13
[réédit] j'ai dis un truc idiot, après essai avec deux tailles de fonte cela n'est pas possible,
Mais avec un texte superposé et la fonction DrawingMode() c'est possible, voir code suivant.
cordialement
peut être avec deux tailles de fonte
exemple: une fonte de 14 en noir et par-dessus une fonte de 12 blanche
ça devrait fonctionner et avoir une fonte de 13
[réédit] j'ai dis un truc idiot, après essai avec deux tailles de fonte cela n'est pas possible,
Mais avec un texte superposé et la fonction DrawingMode() c'est possible, voir code suivant.
cordialement
Dernière modification par kernadec le ven. 21/mars/2014 12:36, modifié 1 fois.
Re: Opération sur les Fonts
test avec un source modifié de danilo (codearchive)
Désolé ce n'est pas top
Cordialement
Désolé ce n'est pas top
Cordialement
Code : Tout sélectionner
; English forum:
; Author: Danilo (updated for PB4.00 by blbltheworm)
; Date: 11. November 2002
; OS: Windows
; Demo: No
; Cool Fonts 1, by Danilo - 11.11.2002
;
#FONT_NORMAL = %00000000
#FONT_BOLD = %00000001
#FONT_ITALIC = %00000010
#FONT_UNDERLINE = %00000100
#FONT_STRIKEOUT = %00001000
Procedure CreateFont(Name$,Size,Style)
If (Style & #FONT_BOLD) : bold = 700 : EndIf
If (Style & #FONT_ITALIC) : italic = 1 : EndIf
If (Style & #FONT_UNDERLINE) : underline = 1 : EndIf
If (Style & #FONT_STRIKEOUT) : strikeout = 1 : EndIf
ProcedureReturn CreateFont_(Size,0,0,0,bold,italic,underline,strikeout,0,0,0,0,0,Name$)
EndProcedure
Procedure CreateMyImage()
Normal = CreateFont("Verdana",48,#FONT_NORMAL)
bold = CreateFont("Script MT Bold",48,#FONT_BOLD)
italic = CreateFont("Verdana",48,#FONT_ITALIC)
underline = CreateFont("Verdana",48,#FONT_UNDERLINE)
strikeout = CreateFont("Verdana",48,#FONT_STRIKEOUT)
Combined1 = CreateFont("Verdana",48,#FONT_BOLD|#FONT_UNDERLINE)
Combined2 = CreateFont("Verdana",48,#FONT_ITALIC|#FONT_UNDERLINE|#FONT_STRIKEOUT|#FONT_BOLD)
image = CreateImage(1,600,400)
StartDrawing(ImageOutput(1))
DrawingMode(1)
Box(0,0,600,400, RGB($ff,$ff,$ff)) ; fond blanc
FrontColor(RGB($00,$00,$00))
; DrawingFont(Normal)
; DrawText(10,10,"PureBasic - normal")
DrawingFont(bold)
DrawText(10,60,"PureBasic - Bold")
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DrawingFont(bold)
DrawingMode(2)
FrontColor(RGB($ff,$ff,$ff))
DrawText(11,61,"PureBasic - Bold")
FrontColor(RGB($00,$00,$00))
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; DrawingMode(1)
; DrawingFont(italic)
; DrawText(10,110,"PureBasic - Italic")
; DrawingFont(Underline)
; DrawText(10,160,"PureBasic - Underline")
; DrawingFont(StrikeOut)
; DrawText(10,210,"PureBasic - StrikeOut")
; DrawingFont(Combined1)
; DrawText(10,260,"PureBasic - Combined 1")
; DrawingFont(Combined2)
; DrawText(10,310,"PureBasic - Combined 2")
StopDrawing()
DeleteObject_(Normal) : DeleteObject_(Bold)
DeleteObject_(Italic) : DeleteObject_(Underline)
DeleteObject_(StrikeOut): DeleteObject_(Combined1)
DeleteObject_(Combined2)
ProcedureReturn image
EndProcedure
OpenWindow(1,100,200,600,400,"Cool Fonts 1",#PB_Window_SystemMenu)
myImage = CreateMyImage()
CreateGadgetList(WindowID(1))
ImageGadget(1,0,0,600,400,myImage)
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: Opération sur les Fonts
Tu pourrais faire un traitement d'image avec une mise en valeur du contour (voir http://www.purebasic.fr/english/viewtop ... ead#unread), ou plutôt regarder du côté de GDI+ qui contient quelques fonctions assez poussées pour le texte :
http://www.purebasic.fr/english/viewtop ... it=drawing
http://purebasic.developpez.com/tutoriels/gdi/#LV-
http://bobpowell.net/texteffects.aspx
http://www.purebasic.fr/english/viewtop ... it=drawing
http://purebasic.developpez.com/tutoriels/gdi/#LV-
http://bobpowell.net/texteffects.aspx
Re: Opération sur les Fonts
Cederavic pour "Barbouille"
m'avait fait une fonction qui ressort les contours
http://www.purebasic.fr/french/viewtopi ... e&start=90
regarde la procedure getEdgeGray(x, y, Array image_tab(2), alternate = #False)
m'avait fait une fonction qui ressort les contours
http://www.purebasic.fr/french/viewtopi ... e&start=90
regarde la procedure getEdgeGray(x, y, Array image_tab(2), alternate = #False)
Re: Opération sur les Fonts
Merci ! J'y jette un œil de suite.
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel )
Mon site : CeriseCode (Attention Chantier perpétuel )
Re: Opération sur les Fonts
Les fonctions de la suite GDI+ sont vraiment sympas, mais limité à windows...
Sinon, en adaptant la fonction getEdge() de manière à cadrer avec mes limitations, je suis parvenu à accélérer le traitement d'une surface de 400x400 de 780ms à 65ms (sur mon ordi)
et obtenir une détection satisfaisante du tour de la police.
L'étape suivante est le réglage de l'épaisseur de ce contour.
Sinon, en adaptant la fonction getEdge() de manière à cadrer avec mes limitations, je suis parvenu à accélérer le traitement d'une surface de 400x400 de 780ms à 65ms (sur mon ordi)
et obtenir une détection satisfaisante du tour de la police.
Code : Tout sélectionner
;{ procedure
Procedure GetEdgeGray(Array image_tab.a(2))
w = ArraySize(image_tab(), 1) - 1
h = ArraySize(image_tab(), 2) - 1
For x = 1 To w
For y = 1 To h
deltaX.l = (image_tab(x + 1, y - 1) + image_tab(x + 1, y) << 1 + image_tab(x + 1, y + 1)) - (image_tab(x - 1, y - 1) + image_tab(x - 1, y) << 1 + image_tab(x - 1, y + 1))
deltaY.l = (image_tab(x - 1, y - 1) + image_tab(x, y - 1) << 1 + image_tab(x + 1, y - 1) ) - (image_tab(x - 1, y + 1) + image_tab(x, y + 1) << 1 + image_tab(x + 1, y + 1))
gray.l = Sqr(deltaX * deltaX + deltaY * deltaY)
If image_tab(x, y) <> 0
gray = 255 - image_tab(x, y)
Else
If gray > 255
gray = 255
ElseIf gray < 0
gray = 0
EndIf
EndIf
Plot(x, y, RGB(gray, gray, gray))
Next
Next
ProcedureReturn gray
EndProcedure
;}
;{ fenetre
OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CanvasGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), #PB_Canvas_Keyboard)
;}
;{ load image
w = 400
h = 400
CreateImage(0, w+1, h+1)
Dim font(10)
For i = 0 To 10
font(i) = LoadFont(#PB_Any, "Arial", i * 2 + 4)
Next
StartDrawing(ImageOutput(0))
y = 5
For i = 0 To 10
DrawingFont(FontID(font(i)))
DrawText(20, 5 + y, "Ceci est un TEST !", #White)
y = y + 1 + TextHeight(" ")
Next
Dim image.a(w+1, h+1)
For x = 1 To w
For y = 1 To h
c = Point(x, y)
image(x, y) = (Red(c) + Green(c) + Blue(c)) / 3
Next
Next
StopDrawing()
;}
DRAW_Police = 1
REDRAW = #True
;{ boucle principale
Repeat
event = WaitWindowEvent()
;{ event
If event = #PB_Event_Gadget
If EventGadget() = 0
If EventType() = #PB_EventType_KeyUp
Select GetGadgetAttribute(0, #PB_Canvas_Key)
Case #PB_Shortcut_Escape
event = #PB_Event_CloseWindow
Case #PB_Shortcut_Space
REDRAW = #True
DRAW_Police = -DRAW_Police
EndSelect
EndIf
EndIf
EndIf
;}
;{ dessin
If REDRAW
StartDrawing(CanvasOutput(0))
Box(0, 0, OutputWidth(), OutputHeight(), 0)
time = ElapsedMilliseconds()
GetEdgeGray(image())
time = ElapsedMilliseconds() - time
DrawText(10, OutputHeight() - 20, Str(time) + " ms")
DrawText(10, OutputHeight() - 40, "ESPACE pour remplir ou non le Texte")
If DRAW_Police = 1
DrawingMode(#PB_2DDrawing_Transparent)
y = 5
For i = 0 To 10
DrawingFont(FontID(font(i)))
DrawText(20, 5 + y, "Ceci est un TEST !", #Red)
y = y + 1 + TextHeight(" ")
Next
EndIf
StopDrawing()
REDRAW = #False
EndIf
;}
Until event = #PB_Event_CloseWindow
;}
End
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel )
Mon site : CeriseCode (Attention Chantier perpétuel )
Re: Opération sur les Fonts
Avec l'épaisseur :
Le problème de ce code est qu'il parcourt plusieurs fois le tableau. Plus le rayon est grand, plus c'est lent !
Code : Tout sélectionner
;{ procedure
Procedure GetEdgeGray(Array image.a(2), rayon = 1)
w = ArraySize(image(), 1) - 1
h = ArraySize(image(), 2) - 1
Dim image_save.a(w + 1, h + 1)
Dim image_tab.a(w + 1, h + 1)
Dim image_tab2.a(w + 1, h + 1)
CopyArray(image(), image_tab2())
For i = 1 To rayon
CopyArray(image_tab2(), image_tab())
For x = 1 To w
For y = 1 To h
If image_tab(x, y) < 255
deltaX_.l = (image_tab(x + 1, y - 1) + image_tab(x + 1, y) << 1 + image_tab(x + 1, y + 1)) - (image_tab(x - 1, y - 1) + image_tab(x - 1, y) << 1 + image_tab(x - 1, y + 1))
deltaY_.l = (image_tab(x - 1, y - 1) + image_tab(x, y - 1) << 1 + image_tab(x + 1, y - 1) ) - (image_tab(x - 1, y + 1) + image_tab(x, y + 1) << 1 + image_tab(x + 1, y + 1))
deltaX.d = deltaX_ / 3
deltaY.d = deltaY_ / 3
gray.l = Sqr(deltaX * deltaX + deltaY * deltaY)
If gray > 0
If image_tab(x, y) > 0
gray = 255 - image(x, y)
Else
If gray > 255
gray = 255
EndIf
EndIf
image_tab2(x, y) = gray
Plot(x, y, RGB(gray, gray, gray))
image_save(x, y) = gray
EndIf
EndIf
Next
Next
Next
EndProcedure
;}
;{ fenetre
OpenWindow(0, 0, 0, 800, 600, "ARRAY", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CanvasGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), #PB_Canvas_Keyboard)
SetActiveGadget(0)
;}
;{ load image
w = 800
h = 400
nb_font = 14
CreateImage(0, w+1, h+1)
Dim font(nb_font)
For i = 0 To nb_font
font(i) = LoadFont(#PB_Any, "Arial", i * 2 + 4)
Next
StartDrawing(ImageOutput(0))
y = 5
For i = 0 To nb_font
DrawingFont(FontID(font(i)))
DrawText(20, 5 + y, "Ceci est un TEST !", #White)
y = y + 1 + TextHeight(" ")
Next
Dim image.a(w+1, h+1)
Dim image2.a(w+1, h+1)
For x = 1 To w
For y = 1 To h
c = Point(x, y)
image(x, y) = (Red(c) + Green(c) + Blue(c)) / 3
Next
Next
StopDrawing()
;}
DRAW_Police = 1
REDRAW = #True
rayon = 3
;{ boucle principale
Repeat
event = WaitWindowEvent()
;{ event
If event = #PB_Event_Gadget
If EventGadget() = 0
If EventType() = #PB_EventType_KeyDown
Select GetGadgetAttribute(0, #PB_Canvas_Key)
Case #PB_Shortcut_Escape
event = #PB_Event_CloseWindow
Case #PB_Shortcut_Space
REDRAW = #True
DRAW_Police = -DRAW_Police
Case #PB_Shortcut_Up
REDRAW = #True
rayon + 1
If rayon > 10 : rayon = 10 : EndIf
Case #PB_Shortcut_Down
REDRAW = #True
rayon - 1
If rayon < 1 : rayon = 1 : EndIf
EndSelect
EndIf
EndIf
EndIf
;}
;{ dessin
If REDRAW
StartDrawing(CanvasOutput(0))
Box(0, 0, OutputWidth(), OutputHeight(), #Blue)
time = ElapsedMilliseconds()
GetEdgeGray(image(), rayon)
time = ElapsedMilliseconds() - time
DrawText(10, OutputHeight() - 20, Str(time) + " ms")
DrawText(10, OutputHeight() - 40, "ESPACE pour remplir ou non le Texte")
DrawText(10, OutputHeight() - 60, "Up / Down pour faire varier le rayon (r = " + Str(rayon) + ")")
Line(0, h, w, 1, 0)
Line(w, 0, 1, h, 0)
If DRAW_Police = 1
DrawingMode(#PB_2DDrawing_Transparent)
y = 5
For i = 0 To nb_font
DrawingFont(FontID(font(i)))
DrawText(20, 5 + y, "Ceci est un TEST !", #Red)
y = y + 1 + TextHeight(" ")
Next
EndIf
StopDrawing()
REDRAW = #False
EndIf
;}
Until event = #PB_Event_CloseWindow
;}
End
Dernière modification par graph100 le sam. 22/mars/2014 0:35, modifié 1 fois.
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel )
Mon site : CeriseCode (Attention Chantier perpétuel )
Re: Opération sur les Fonts
peut etre plus simplement remplacer
par un Circle ... avec le rayon qui fait la taille non ?
Code : Tout sélectionner
Plot(x, y, RGB(gray, gray, gray))
Re: Opération sur les Fonts
Marche très bien chez moi.
C'est plus doux avec ces modifications:
Ligne 157:
DrawingMode(#PB_2DDrawing_Transparent | #PB_2DDrawing_AlphaClip )
GetEdgeGray(image(), rayon)
Ligne 47:
Plot(x, y, RGBA(gray, gray, gray, 180 ))
C'est plus doux avec ces modifications:
Ligne 157:
DrawingMode(#PB_2DDrawing_Transparent | #PB_2DDrawing_AlphaClip )
GetEdgeGray(image(), rayon)
Ligne 47:
Plot(x, y, RGBA(gray, gray, gray, 180 ))
Re: Opération sur les Fonts
Ça donne un effet vraiment bizarre ! Mais ce qui m'intéresse est de récupérer le tableau de point, et non l'image. Le rendu graphique est effectué ensuite en fonction d'un angle.Dobro a écrit :peut etre plus simplement remplacer
par un Circle ... avec le rayon qui fait la taille non ?Code : Tout sélectionner
Plot(x, y, RGB(gray, gray, gray))
@nico : j'ai essayé, mais le résultat est étrange pour un fond autre que noir, ça laisse des artefacts de partout
et enfin, comme ce que j'ai dis pour Dobro, c'est le tableau de point qui est le rendu voulu.
Ensuite ce tableau est utilisé dans des opérations de rotation et composition avec les couleurs de police / contour / fond, etc...
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel )
Mon site : CeriseCode (Attention Chantier perpétuel )
Re: Opération sur les Fonts
Le même résultat en passant par une liste chainée.
L'exécution est bien plus rapide pour les grandes images, et un grand rayon (en comparaison avec la méthode Array)
J'en ai profité pour ajouter la rotation antialisée (Merci Luis !)
L'exécution est bien plus rapide pour les grandes images, et un grand rayon (en comparaison avec la méthode Array)
J'en ai profité pour ajouter la rotation antialisée (Merci Luis !)
Code : Tout sélectionner
;{ procedure
Procedure GetEdgeGray(Array image.a(2), rayon = 1)
w = ArraySize(image(), 1) - 1
h = ArraySize(image(), 2) - 1
Dim image_save.a(w + 1, h + 1)
Dim image_tab.a(w + 1, h + 1)
Dim image_tab2.a(w + 1, h + 1)
Dim *adr.POINT(w + 1, h + 1)
CopyArray(image(), image_tab2())
NewList coord.POINT()
NewList new_coord.POINT()
Macro AjoutPoint(_x_, _y_)
If *adr(_x_, _y_) = 0 And image_tab(_x_, _y_) = 0 And _x_ < w + 1 And _y_ < h + 1 And _x_ > 0 And _y_ > 0
AddElement(new_coord())
*adr(_x_, _y_) = @new_coord()
new_coord()\x = _x_
new_coord()\y = _y_
EndIf
EndMacro
CopyArray(image(), image_tab())
;{ init
For x = 1 To w
For y = 1 To h
If image_tab(x, y) < 255
deltaX_.l = (image_tab(x + 1, y - 1) + image_tab(x + 1, y) << 1 + image_tab(x + 1, y + 1)) - (image_tab(x - 1, y - 1) + image_tab(x - 1, y) << 1 + image_tab(x - 1, y + 1))
deltaY_.l = (image_tab(x - 1, y - 1) + image_tab(x, y - 1) << 1 + image_tab(x + 1, y - 1) ) - (image_tab(x - 1, y + 1) + image_tab(x, y + 1) << 1 + image_tab(x + 1, y + 1))
deltaX.d = deltaX_ / 3
deltaY.d = deltaY_ / 3
gray.l = Sqr(deltaX * deltaX + deltaY * deltaY)
If gray > 0 Or image_tab(x, y) > 0
If image_tab(x, y) > 0
gray = 255 - image_tab(x, y)
ElseIf gray > 255
gray = 255
EndIf
image_tab2(x, y) = gray
;{ ajout des points futurs
If *adr(x, y) <> 0
ChangeCurrentElement(new_coord(), *adr(x, y))
DeleteElement(new_coord())
*adr(x, y) = -1
EndIf
AjoutPoint(x+1, y)
AjoutPoint(x, y+1)
AjoutPoint(x-1, y)
AjoutPoint(x, y-1)
AjoutPoint(x+1, y+1)
AjoutPoint(x+1, y-1)
AjoutPoint(x-1, y+1)
AjoutPoint(x-1, y-1)
;}
If rayon > 1
image_save(x, y) = 255-image_tab(x, y)
Else
image_save(x, y) = gray
EndIf
;Plot(x, y, RGB(image_save(x, y), image_save(x, y), image_save(x, y)))
EndIf
EndIf
Next
Next
;}
;{ boucle normale
For i = 2 To rayon
CopyList(new_coord(), coord())
CopyArray(image_tab2(), image_tab())
Dim *adr.POINT(w + 1, h + 1)
ClearList(new_coord())
ForEach coord()
x = coord()\x
y = coord()\y
If image_save(x, y) < 255
deltaX_.l = (image_tab(x + 1, y - 1) + image_tab(x + 1, y) << 1 + image_tab(x + 1, y + 1)) - (image_tab(x - 1, y - 1) + image_tab(x - 1, y) << 1 + image_tab(x - 1, y + 1))
deltaY_.l = (image_tab(x - 1, y - 1) + image_tab(x, y - 1) << 1 + image_tab(x + 1, y - 1) ) - (image_tab(x - 1, y + 1) + image_tab(x, y + 1) << 1 + image_tab(x + 1, y + 1))
deltaX.d = deltaX_ / 3
deltaY.d = deltaY_ / 3
gray.l = Sqr(deltaX * deltaX + deltaY * deltaY)
If gray > 0 Or image_save(x, y) > 0
If image_tab(x, y) > 0
gray = 255 - image(x, y)
ElseIf gray > 255
gray = 255
EndIf
image_tab2(x, y) = gray
;{ ajout des points futurs
If *adr(x, y) <> 0
ChangeCurrentElement(new_coord(), *adr(x, y))
DeleteElement(new_coord())
*adr(x, y) = -1
EndIf
AjoutPoint(x+1, y)
AjoutPoint(x, y+1)
AjoutPoint(x-1, y)
AjoutPoint(x, y-1)
AjoutPoint(x+1, y+1)
AjoutPoint(x+1, y-1)
AjoutPoint(x-1, y+1)
AjoutPoint(x-1, y-1)
;}
If i < rayon
image_save(x, y) = 255
Else
image_save(x, y) = gray
EndIf
;Plot(x, y, RGB(image_save(x, y), image_save(x, y), image_save(x, y)))
EndIf
EndIf
Next
Next
;}
CopyArray(image_save(), image())
EndProcedure
Procedure DrawRotatedArrayGray(Array image.a(2), centre_x, centre_y, x, y, Angle.d, couleur.l, Antialiasing = #True)
Protected.d Angle_Cos, Angle_Sin
Protected.l w, h, iXc1, iYc1, iXc2, iYc2, iXs, iYs
x - 1
y - 1
red.d = Red(Couleur) / 255
green.d = Green(Couleur) / 255
blue.d = Blue(Couleur) / 255
x_max.l = OutputWidth() - 1
y_max.l = OutputHeight() - 1
Angle_Cos = Cos(Angle)
Angle_Sin = Sin(Angle)
w_source = ArraySize(image(), 1) ;- 1
h_source = ArraySize(image(), 2) ;- 1
w = Int(w_source * Abs(Angle_Cos) + h_source * Abs(Angle_Sin))
h = Int(h_source * Abs(Angle_Cos) + w_source * Abs(Angle_Sin))
iXc1 = w_source >> 1
iYc1 = h_source >> 1
iXc2 = w >> 1
iYc2 = h >> 1
c.d = x + iXc1
d.d = y + iYc1
new_angle.d = ATan2(c, d) + Angle; * #PI / 180
dist.d = Sqr(c * c + d * d)
c = centre_x + dist * Cos(new_angle) - iXc2
d = centre_y + dist * Sin(new_angle) - iYc2
Select Antialiasing
Case #False
For iY = 0 To h - 1
For iX = 0 To w - 1
; For each nDestImage point find rotated nSrcImage source point
iXs = iXc1 + (iX - iXc2) * Angle_Cos + (iY - iYc2) * Angle_Sin
iYs = iYc1 + (iY - iYc2) * Angle_Cos - (iX - iXc2) * Angle_Sin
If iXs >= 0 And iXs < w_source And iYs >= 0 And iYs < h_source
a = c + iX
b = d + iY
If a >= 0 And a < x_max And b >= 0 And b < y_max
color.l = Point(a, b)
tmp.a = 255 - image(iXs, iYs)
; Plot(a, b, RGB(image(iXs, iYs) * red, image(iXs, iYs) * green, image(iXs, iYs) * blue))
Plot(a, b, RGB(image(iXs, iYs) * red + tmp * Red(color) / 255, image(iXs, iYs) * green + tmp * Green(color) / 255, image(iXs, iYs) * blue + tmp * Blue(color) / 255))
EndIf
EndIf
Next
Next
Case #True
For iY = 0 To h - 1
For iX = 0 To w - 1
; For each nDestImage point find rotated nSrcImage source point
fXs.d = iXc1 + (iX - iXc2) * Angle_Cos + (iY - iYc2) * Angle_Sin
fYs.d = iYc1 + (iY - iYc2) * Angle_Cos - (iX - iXc2) * Angle_Sin
; iXs0 = Int(fXs) ; Strange behaviour when pixel have color for fXs, fYs near 0
; iYs0 = Int(fYs)
iXs0 = Round(fXs, #PB_Round_Down)
iYs0 = Round(fYs, #PB_Round_Down)
If iXs0 >= 0 And iXs0 < w_source - 1 And iYs0 >= 0 And iYs0 < h_source - 1
a = c + iX
b = d + iY
If a >= 0 And a < x_max And b >= 0 And b < y_max
; Bottom left coords of bounding floating point rectangle on nSrcImage
fXfs1.d = fXs - Int(fXs)
fYfs1.d = fYs - Int(fYs)
fXfs1less.d = 1 - fXfs1 - 0.000005 : If fXfs1less < 0 : fXfs1less = 0 : EndIf
fYfs1less.d = 1 - fYfs1 - 0.000005 : If fYfs1less < 0 : fYfs1less = 0 : EndIf
ic0.d = image(iXs0 + 1, iYs0) * fXfs1 + image(iXs0, iYs0) * fXfs1less
ic1.d = image(iXs0 + 1, iYs0 + 1) * fXfs1 + image(iXs0, iYs0 + 1) * fXfs1less
; Weight along axis Y
ic = fYfs1less * ic0 + fYfs1 * ic1
color.l = Point(a, b)
tmp.a = 255 - ic
Plot(a, b, RGB(ic * red + tmp * Red(color) / 255, ic * green + tmp * Green(color) / 255, ic * blue + tmp * Blue(color) / 255))
EndIf
ElseIf iXs0 = w_source - 1 And iYs0 >= 0 And iYs0 < h_source - 1
a = c + iX
b = d + iY
If a >= 0 And a < x_max And b >= 0 And b < y_max
; Bottom left coords of bounding floating point rectangle on nSrcImage
fXfs1.d = fXs - Int(fXs)
fYfs1.d = fYs - Int(fYs)
fXfs1less.d = 1 - fXfs1 - 0.000005 : If fXfs1less < 0 : fXfs1less = 0 : EndIf
fYfs1less.d = 1 - fYfs1 - 0.000005 : If fYfs1less < 0 : fYfs1less = 0 : EndIf
ic0.d = image(iXs0, iYs0) * fXfs1less
ic1.d = image(iXs0, iYs0 + 1) * fXfs1less
; Weight along axis Y
ic = fYfs1less * ic0 + fYfs1 * ic1
color.l = Point(a, b)
tmp.a = 255 - ic
Plot(a, b, RGB(ic * red + tmp * Red(color) / 255, ic * green + tmp * Green(color) / 255, ic * blue + tmp * Blue(color) / 255))
EndIf
ElseIf iXs0 >= 0 And iXs0 < w_source - 1 And iYs0 = h_source - 1
a = c + iX
b = d + iY
If a >= 0 And a < x_max And b >= 0 And b < y_max
; Bottom left coords of bounding floating point rectangle on nSrcImage
fXfs1.d = fXs - Int(fXs)
fXfs1less.d = 1 - fXfs1 - 0.000005 : If fXfs1less < 0 : fXfs1less = 0 : EndIf
fYfs1less.d = 1 - fYfs1 - 0.000005 : If fYfs1less < 0 : fYfs1less = 0 : EndIf
ic0.d = image(iXs0 + 1, iYs0) * fXfs1 + image(iXs0, iYs0) * fXfs1less
; Weight along axis Y
ic = fYfs1less * ic0
color.l = Point(a, b)
tmp.a = 255 - ic
Plot(a, b, RGB(ic * red + tmp * Red(color) / 255, ic * green + tmp * Green(color) / 255, ic * blue + tmp * Blue(color) / 255))
EndIf
EndIf
Next
Next
EndSelect
EndProcedure
;}
;{ fenetre
OpenWindow(0, 0, 0, 800, 600, "LIST", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CanvasGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), #PB_Canvas_Keyboard)
SetActiveGadget(0)
;}
;{ load image
w = 800
h = 400
nb_font = 14
CreateImage(0, w+1, h+1)
Dim font(nb_font)
For i = 0 To nb_font
font(i) = LoadFont(#PB_Any, "Arial", i * 2 + 4)
Next
StartDrawing(ImageOutput(0))
y = 5
For i = 0 To nb_font
DrawingFont(FontID(font(i)))
DrawText(20, 5 + y, "Ceci est un TEST !", #White)
y = y + 1 + TextHeight(" ")
Next
Dim image.a(w+1, h+1)
Dim image2.a(w+1, h+1)
For x = 1 To w
For y = 1 To h
c = Point(x, y)
image(x, y) = (Red(c) + Green(c) + Blue(c)) / 3
Next
Next
StopDrawing()
;}
REDRAW = #True
angle = 20
rayon = 3
;{ boucle principale
Repeat
event = WaitWindowEvent()
;{ event
If event = #PB_Event_Gadget
If EventGadget() = 0
If EventType() = #PB_EventType_KeyDown
Select GetGadgetAttribute(0, #PB_Canvas_Key)
Case #PB_Shortcut_Escape
event = #PB_Event_CloseWindow
Case #PB_Shortcut_Up
REDRAW = #True
angle + 10
If angle > 360 : angle - 360 : EndIf
Case #PB_Shortcut_Down
REDRAW = #True
angle - 10
If angle < 0 : angle + 360 : EndIf
Case #PB_Shortcut_Left
REDRAW = #True
rayon + 1
If rayon > 10 : rayon = 10 : EndIf
Case #PB_Shortcut_Right
REDRAW = #True
rayon - 1
If rayon < 1 : rayon = 1 : EndIf
EndSelect
EndIf
EndIf
EndIf
;}
;{ dessin
If REDRAW
StartDrawing(CanvasOutput(0))
Box(0, 0, OutputWidth(), OutputHeight(), #Blue)
time = ElapsedMilliseconds()
CopyArray(image(), image2())
GetEdgeGray(image2(), rayon)
DrawRotatedArrayGray(image2(), 400, 0, 0, 0, angle * #PI / 180, #Red)
time = ElapsedMilliseconds() - time
DrawText(10, OutputHeight() - 20, Str(time) + " ms")
DrawText(10, OutputHeight() - 40, "Up / Down pour faire varier l'angle (alpha = " + Str(angle) + "°)")
DrawText(10, OutputHeight() - 60, "Left / Rigth pour faire varier le rayon (rayon = " + Str(rayon) + ")")
StopDrawing()
REDRAW = #False
EndIf
;}
Until event = #PB_Event_CloseWindow
;}
End
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel )
Mon site : CeriseCode (Attention Chantier perpétuel )
Re: Opération sur les Fonts
Magnifique, merci pour le partage.
Re: Opération sur les Fonts
Le résultat est super propre, même avec la rotation + modification d’épaisseur.
Bravo.
Bravo.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Re: Opération sur les Fonts
bonjour Graph100
Merci pour le partage, vraiment top la classe, je suis impressionné!
Cordialement
Merci pour le partage, vraiment top la classe, je suis impressionné!
Cordialement