[Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von c4s »

Echt fein was du da auf die Beine gestellt hast. Ich kann einiges davon gebrauchen. Also auch von mir ein großes Lob! :allright:
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von Falko »

+1 :allright:
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von STARGÅTE »

Tachchen Danilo,

ich nutze nun dein Include aktiv für ein Projekt und die Arbeit damit ist auch toll :allright:

Leider bin ich auf ein kleines Hindernis gestoßen, von dem ich hoffe, dass man es irgendwie umgehen kann:
Zeichnet man mehrere halbtransparente Linien an einander (wie auch immer), so kommt an an den Collisionspunkten zu hässlichen AntiAliasing-Fehlern (überlagerung oder löcher). Ich weiß das es dafür eigentlich Pfade gibt bzw. Polygone, jedoch gibt es auch mal die Situation, dass ich eine Box mit einer Linie verbinden will.
Die Frage ist nun, ob es bei GDI+ auch die möglichkeit gibt, Elemente "gleichzeitig" zeichnen zu lassen, also als Gruppe, als wären sie ein Element?

Wenn ja, könntest du das noch einbinden?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von Danilo »

STARGÅTE hat geschrieben:Die Frage ist nun, ob es bei GDI+ auch die möglichkeit gibt, Elemente "gleichzeitig" zeichnen zu lassen, also als Gruppe, als wären sie ein Element?
Kannst Du vielleicht mal ein Beispiel schreiben, wo man sehen kann, was
Du ungefähr machen möchtest? Verstehe es noch nicht so ganz, also z.B.
Box mit Linie verbinden oder so...?

Nicht-geschlossene Elemente (z.B. Punkte, Linien) kann man mit Paths
und gClosePath() zu einer Gruppe verbinden, so als wären sie ein Element.

Beispiel mit 2 Linien, die automatisch zu einer geschlossenen Figur verbunden werden:

Code: Alles auswählen

EnableExplicit

XIncludeFile "gDrawing.pbi"

Define img

Procedure Draw(image)
    If gStartDrawing( ImageOutput(image) )
        gClear(RGBA($80,$80,$80,$FF))
        gSetPenSize(2)

        gDrawingMode(#PB_2DDrawing_Path)
            gLine(300,100,0, 100)
            gLine(400,250,0,-100)
            gClosePath()
        gDrawingMode(#PB_2DDrawing_Default)
            gDrawPath(#PB_Default,RGBA($FF,$FF,$00,$FF))   ; draw current path with yellow color
        gDrawingMode(#PB_2DDrawing_Outlined)
            gDrawPath(#PB_Default,RGBA($00,$00,$00,$FF))   ; draw current path outlined with black color

        gStopDrawing()
    EndIf
EndProcedure

If gInit()

    img = CreateImage(#PB_Any,800,600)
    Draw(img)

    OpenWindow(#PB_Any,0,0,800,600,"gDrawing",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    ImageGadget(#PB_Any,0,0,800,600,ImageID( img ))
    Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow

    gEnd()
EndIf
Oder hier ein Beispiel mit "mehrere halbtransparente Linien an einander (wie auch immer)":

Code: Alles auswählen

EnableExplicit

XIncludeFile "gDrawing.pbi"

Define img
Global i

Procedure Draw(image)
    If gStartDrawing( ImageOutput(image) )
        gClear(RGBA($80,$80,$80,$FF))
        gSetPenSize(3)

        gLineXY(100,200,420,500,$FF000000) ; 2 schwarze Linien
        gLineXY(400,200,120,500,$FF000000)

        gSetPenSize(1)
        gDrawingMode(#PB_2DDrawing_Path)
            For i = 0 To 300
                gLineXY(100+i,200,120+i,500) ; mehrere Linien an einander
                gLineXY(121+i,500,101+i,200)
            Next i
            gClosePath()

        gDrawingMode(#PB_2DDrawing_Default)
            gDrawPath(#PB_Default,RGBA($FF,$FF,$00,$80)) ; zeichne "mehrere halbtransparente Linien an einander (wie auch immer)"

        gStopDrawing()
    EndIf
EndProcedure

If gInit()

    img = CreateImage(#PB_Any,800,600)
    Draw(img)

    OpenWindow(#PB_Any,0,0,800,600,"gDrawing",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    ImageGadget(#PB_Any,0,0,800,600,ImageID( img ))
    Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow

    gEnd()
EndIf
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von STARGÅTE »

Erst mal danke für die beiden Beispiele, aber irgendwie ist gClosePath() nicht das richtige, weil es alle offnenen Ende zusammen fügt.

Hier mal ein ganz einfaches Beispiel:

Wie kann ich ein Kreuz mit zwei Linien zeichnen, ohne das die Mitte dunkler wird, ohne "stückeln zu müssen":

Code: Alles auswählen

Enumeration
	#Image
EndEnumeration

IncludePath "C:\Includes\PureBasic"
XIncludeFile "gDrawing.pbi"

gInit()

CreateImage(#Image, 600, 600, 32|#PB_Image_Transparent)

gStartDrawing(ImageOutput(#Image))
  gClear($FFFFFFFF)
  gSetPenSize(50)
  gLineXY(100,100,500,500,$80000000)
  gLineXY(500,100,100,500,$80000000)
gStopDrawing()


SetClipboardImage(#Image)


OpenWindow(#PB_Any, 0, 0, ImageWidth(#Image), ImageHeight(#Image), "Image", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
 ImageGadget(#PB_Any, 0, 0, ImageWidth(#Image), ImageHeight(#Image), ImageID(#Image))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

gEnd()
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von Danilo »

STARGÅTE hat geschrieben:Erst mal danke für die beiden Beispiele, aber irgendwie ist gClosePath() nicht das richtige, weil es alle offnenen Ende zusammen fügt.

Hier mal ein ganz einfaches Beispiel:

Wie kann ich ein Kreuz mit zwei Linien zeichnen, ohne das die Mitte dunkler wird, ohne "stückeln zu müssen":
Danke, nun weiß ich was Du meinst. Dafür bräuchte man sowas wie gLines() um mehrere
Linien mit einmal zu zeichnen.
Ist noch auf der ToDo-Liste, allerdings schon eine Weile nichts mehr gemacht:

Code: Alles auswählen

gLines(), gLinesXY(), gBoxes(), gBeziers(), gCurves(), gClosedCurves()
Also Funktionen um mehrere Figuren auf einmal zu zeichnen.

Für den Moment ein kleiner Workaround:

Code: Alles auswählen

Enumeration
   #Image
EndEnumeration

;IncludePath "C:\Includes\PureBasic"
XIncludeFile "gDrawing.pbi"

gInit()

CreateImage(#Image, 600, 600, 32|#PB_Image_Transparent)

gStartDrawing(ImageOutput(#Image))
  gClear($FFFFFFFF)
  gSetPenSize(50)
  gDrawingMode(#PB_2DDrawing_Path)
  gLineXY(100,100,500,500)
  gLineXY(500,500,300,300) ; zurueck zum mittelpunkt
  gLineXY(500,100,100,500)
  gDrawingMode(#PB_2DDrawing_Outlined)
  gDrawPath(#PB_Default,$80000000) ; zeichne "mehrere halbtransparente Linien an einander (wie auch immer)"

gStopDrawing()


SetClipboardImage(#Image)


OpenWindow(#PB_Any, 0, 0, ImageWidth(#Image), ImageHeight(#Image), "Image", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(#PB_Any, 0, 0, ImageWidth(#Image), ImageHeight(#Image), ImageID(#Image))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

gEnd()
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von STARGÅTE »

Ah alles klar.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von STARGÅTE »

Muss noch mal einen kleinen Bug melden:

Wie es aussieht, wird bei gTextWidth() nicht der TextAntialiasMode beachtet:

Code: Alles auswählen

Enumeration
   #Image
EndEnumeration

; IncludePath "C:\Includes\PureBasic"
XIncludeFile "gDrawing.pbi"

gInit()

CreateImage(#Image, 740, 600, 32|#PB_Image_Transparent)

Define Text.s = "Das ist ein ganz langer Text, von dem die Breite ermittelt wird"
gStartDrawing(ImageOutput(#Image))
	gSetFont("Arial", 24)
	gClear($FFFFFFFF)
	gSetTextAntialiasMode(#TextAntialiasMode_SystemDefault)
	gBox(0, 0, gTextWidth(Text), gTextHeight(Text), $FFC0C0C0)
	gDrawText(0, 0, Text, $FF000000)
	gSetTextAntialiasMode(#TextAntialiasMode_ClearTypeGridFit)
	gBox(0, 60, gTextWidth(Text), gTextHeight(Text), $FFC0C0C0)
	gDrawText(0, 60, Text, $FF000000)
	gSetTextAntialiasMode(#TextAntialiasMode_AntiAlias)
	gBox(0, 120, gTextWidth(Text), gTextHeight(Text), $FFC0C0C0)
	gDrawText(0, 120, Text, $FF000000)
gStopDrawing()


SetClipboardImage(#Image)


OpenWindow(#PB_Any, 0, 0, ImageWidth(#Image), ImageHeight(#Image), "Image", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(#PB_Any, 0, 0, ImageWidth(#Image), ImageHeight(#Image), ImageID(#Image))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

gEnd()
Bild

Es wird immer die Breite von #TextAntialiasMode_AntiAlias zurück gegeben.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von Danilo »

STARGÅTE hat geschrieben:Muss noch mal einen kleinen Bug melden:

Wie es aussieht, wird bei gTextWidth() nicht der TextAntialiasMode beachtet:
[...]
Bild

Es wird immer die Breite von #TextAntialiasMode_AntiAlias zurück gegeben.
Vielen Dank, STARGÅTE!

Probier mal bitte mit gDrawing_v0.81b.zip und sage bitte ob es nun besser passt. Danke!

Dabei sind ohne Antialiasing immernoch ein paar Pixel mehr da, aber jetzt nur ein paar wenige, auch bei großen Fonts (stört das noch?).
Dein erster BugReport wäre damit auch behoben, daß gDrawText() gegenüber DrawText() zuviel Abstand hat.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: [Windows] 2DDrawing Befehle mit AntiAliasing durch GDI+

Beitrag von STARGÅTE »

Jo, danke, scheint nun besser zu sein.
Dein erster BugReport wäre damit auch behoben
Jo, danke dafür.
Nun kann ich besser Texte stückeln, da nun z.B. gTextWidth("AB")+gTextWidth("CD") gelcih gTextWidth("ABCD") ist.

Was mich jedoch noch wundert ist: abschließende Leerzeichen gehen nicht mit in die Breite ein.
gTextWidth("A") = gTextWidth("A ")
Klar, sie werden ja nicht angezeigt, aber trotzdem haben sie eine Länge und gerade wenn man (wie ich) einen Cursor anzeigen lassen will, brauche ich auch diese Leerzeichen.

Gibt es da vielleicht noch n Flag ?^^

Ansonsten muss ich n Punkt anhängen und dann die Breite wieder abziehen, dass geht ja nun ^^
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten