Antialiased Drawing

Für allgemeine Fragen zur Programmierung mit PureBasic.
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Antialiased Drawing

Beitrag von Lambda »

Kennt jemand einen Filter dafür? Gerade RoundedBox macht sehr unschöne Ränder. Muss nicht gerade eine Lösung für Spiele sein. (CanvasGadget)

lg :D
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Antialiased Drawing

Beitrag von NicTheQuick »

Vielleicht gDrawing?
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Antialiased Drawing

Beitrag von Lambda »

Ein Filter wäre mir etwas lieber als der GDI extra Kram ^^
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Antialiased Drawing

Beitrag von STARGÅTE »

Dafür kannst du den Filter von hier nutzen:
RoundImageFilterCallback

Den Filter kannst du aber nur auf eine Box anwenden.

Für Lines und Ellipsen wäre ein solcher Filter einfach zu langsam.
Dann lieber GDI+
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
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Antialiased Drawing

Beitrag von Lambda »

Und er funktioniert auch bei Verwendung von Gradianten? Die Box ist nämlich nichtmehr sichtbar wenn ich es verwende.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Antialiased Drawing

Beitrag von STARGÅTE »

Klar geht das.

Der CustomFilterCallback macht nix anderes, als die Farbe die theoretisch gezeichnet wird und die Farbe die der Untergrund hat, an den Callback zu geben. Dort kannst du dann das "verhalten" (im Normalfall AlphaBlend(SourceColor, DestinationColor)) ändern.

Hier ein Beispiel für ein LinearGradient mit einer Box die aber dann zum Kreis gefiltert wird, welcher 25 Pixel Unschärfe-Rand hat.

Code: Alles auswählen


Enumeration
	#Window
	#Gadget
EndEnumeration


Procedure FilterCallback(X.i, Y.i, SourceColor, DestinationColor)
	; X, Y - Koordinaten
	; SourceColor - Farbe die gezeichnet werden soll (vom Gradien oder die angabe in Box)
	; DestinationColor - Untergrundfarbe
	Protected Distance.f = Sqr(Pow(X-OutputWidth()/2,2)+Pow(Y-OutputHeight()/2,2))
	Protected Alpha.a
	If Distance > 125
		SourceColor = $00000000
	ElseIf Distance > 100
		Alpha = Alpha(SourceColor)*(125-Distance)/25
		SourceColor & $00FFFFFF | Alpha << 24
	EndIf
	ProcedureReturn AlphaBlend(SourceColor, DestinationColor)
EndProcedure


OpenWindow(#Window, 0, 0, 256, 256, "Beispiel", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))


If StartDrawing(CanvasOutput(#Gadget))
	Box(0, 0, OutputWidth()/2, OutputHeight()/2, $000000)
	Box(OutputWidth()/2, OutputHeight()/2, OutputWidth()/2, OutputHeight()/2, $000000)
	DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_CustomFilter)
	CustomFilterCallback(@FilterCallback())
	LinearGradient(0, 0, OutputWidth()-1, OutputHeight()-1)
		GradientColor(0.0, $FFFF8000)
		GradientColor(1.0, $FF00FF80)
	Box(0, 0, OutputWidth(), OutputHeight())
	StopDrawing()
EndIf


Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Bild
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
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Antialiased Drawing

Beitrag von Lambda »

Absolut perfektes Beispiel. :allright:

Nur leider versteh ich die Gebrauchsweise davon nicht richtig. Wie kann ich zb den radius so minimieren das daraus nur weiche kanten werden. Oder wenn ich für die nächste Form eine ganz andere Farbe verwende?
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Antialiased Drawing

Beitrag von STARGÅTE »

Hier mal etwas detailierter was passiert, wenn du ein CustomFilterCallback benutzt:
  • Nehmen wir mal an, das gesamte Bild (200 x 200 Pixel) ist vorher Rot.
  • Du rufst nun (nach CustomFilterCallback) den Befehl Box(50, 50, 100, 100, RGBA(0,0,255,128))
  • Ohne den Callback würde nun eine Box mit halbtransparentem Blau auf das Rot gezeichnet werden.
  • Durch den Filter passiert nun folgendes:
  • Jeder Pixel, der durch Box() gezeinet werden würde, wird mit seinen Koordinaten, der Untergrundfarbe (Rot) und der Zeichnen-Farbe (halbtransparentes Blau) an den Filter gegeben.
  • Im Filter errechnen ich nun zB den Abstand des Pixels zum Bildzentrum (für Kreis).
  • Ist der Abstand > 50 Pixel, wird der Pixel nicht gezeichnet.
  • ist der Abstand (Float) zwischen 49 und 50 Pixel (normale Kantenglättung), muss er "geglättet" werden, also ändere ich den Alpha-Wert der Zeichenfarbe, um den Pixel abzuschwächen.
  • Ist der Abstand <= 99 Pixel, wird der Pixel normal gezeichnet.

Code: Alles auswählen


Enumeration
	#Window
	#Gadget
EndEnumeration

Global Radius.f = 50


Procedure FilterCallback(X.i, Y.i, SourceColor, DestinationColor)
	Protected Distance.f = Sqr(Pow(X-OutputWidth()/2,2)+Pow(Y-OutputHeight()/2,2))
	Protected Alpha.a
	If Distance > Radius
		SourceColor = $00000000
	ElseIf Distance > Radius-1
		Alpha = Alpha(SourceColor)*(Radius-Distance)
		SourceColor & $00FFFFFF | Alpha << 24
	EndIf
	ProcedureReturn AlphaBlend(SourceColor, DestinationColor)
EndProcedure


OpenWindow(#Window, 0, 0, 200, 200, "Beispiel", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))


If StartDrawing(CanvasOutput(#Gadget))
	Box(0, 0, 200, 200, RGBA(255,0,0,255))
	DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_CustomFilter)
	CustomFilterCallback(@FilterCallback())
	Box(50, 50, 100, 100, RGBA(0,0,255,128))
	StopDrawing()
EndIf

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Das heißt, was genau der Filter machen soll, muss du selber schreiben.
Was bei einem Kreis noch einfach ist (Glättung) ist bei einer Linie schon schwerer.
Das heißt, herauszufinden, wie der zu zeichnende Pixel verändert werden muss. (mehr Berechungen).
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
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Antialiased Drawing

Beitrag von Lambda »

Schön erklärt :allright: mal sehn was sich so zusammenklopfen lässt.

Etwas offtopic aber ich möchte dazu kein extra Thread eröffnen. Wenn ich eine "Ribbon" ähnliche Toolbar programmiere ist das rechtlich ok? Es wäre vom funktionellem wie ein Panel mit dem man zwischen Toolbars schalten kann, was aber ähnlich aussieht wie eine Ribbonleiste.
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3875
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Antialiased Drawing

Beitrag von bobobo »

ämm -- Bilder muss man gar nicht malen zum Zeitpunkt wenn man sie braucht sondern kann
die auch vorab basteln und dann passend einbauen. Dann sollte das mit dem Antialiasing eigent-
lich gar kein Problem mehr sein.

Das sollte auch energetisch günstiger sein :)
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Antworten