VisualBasic mehrere Kreise mit Farbverläufen zeichnen

Bl4ckbyt3

Cadet 3rd Year
Registriert
Juli 2010
Beiträge
43
Hallo CB'ler,

ich stehe vor einer "kleinen" Aufgabe die ich nicht hinbekomme und euch deswegen um Rat bete. Es geht darum eine Grafik in VB.net nachzubilden um diese Anschließend in einer anderen Anwendung wiederverwenden zu können. Die Grafik um die es hier geht sieht folgendermaßen aus:

praesenz.png


Ich habe zwar schon eine Weile gesucht, aber das einzigst brauchbare was ich bisher gefunden habe ist das hier obwohl das auch nur teilweiße brauchbar ist.

Code:
Dim g As Graphics = Me.CreateGraphics()
        g.Clear(Me.BackColor)
        g.SmoothingMode = SmoothingMode.AntiAlias
        ' Create a Graphics path
        Dim path As New GraphicsPath
        ' Add two lines, a rectangle, and 
        ' an ellipse
        path.AddLine(20, 20, 200, 20)
        path.AddLine(20, 20, 20, 200)
        path.AddRectangle(New Rectangle(30, 30, 100, 100))
        path.AddEllipse(New Rectangle(50, 50, 60, 60))
        ' Draw path
        Dim redPen As New Pen(Color.Red, 2)
        g.DrawPath(redPen, path)
        g.FillPath(New SolidBrush(Color.Black), path)
        ' Dispose
        redPen.Dispose()
        g.Dispose()

Ich hoffe doch, dass mir jemand weiterhelfen kann und ich nicht mit unnötigen let-me-google-that-for-you Links zutun bekomme. Habt bitte auch erbarmen dafür, dass ich noch ein Anfänger auf diesem Gebiet bin!

Danke schonmal :-)
 
bei solchen Grafiken hast du 2 Möglichkeiten:

1. Verwenden von Grafiken, also den wirklichen Dateien

2. Erzeugen der Grafik.

aus deinem Post entnehme ich, dass du Möglichkeit 2 verwenden willst.

Wenn das der Fall ist musst du die Grafik aus Teilen zusammensetzen. Im Beispielsbild siehe ich dort:

1. Hintergrund
2. Grüner Kreis
3. dunkelgrüner Kreisrahmen
4. Fenster-Gloss-Effekt
5. Glanzlicht

Dies zeichnest du alles nacheinander auf die Zeichenfläche. Diese musst du erstmal anlegen. Am einfachsten geht das mit einer Bitmap

Code:
Dim meinBild as System.Drawing.Bitmap = new System.Drawing.Bitmap(50,50)

Das wäre jetzt eine 50x50 Grafik.
Dann kannst du dir den Grafikkontext holen, welcher ermöglicht auf dem Bild zu zeichnen
Code:
Dim g as Graphics = System.Drawing.Graphics.FromImage(meinBild)

Nun kannst du die Zahlreichen Grafikfunktionen benutzen. Für die meisten braucht man jedoch noch Zeichenwerkzeuge. Im Allgemeinen gilt: Willst du eine Linie Zeichnen (ganz egal welcher form) brauchst du einen Pen, wenn du eine fläche Zeichnen willst einen Brush.
Linien sind einfach:
Code:
Dim stift as new Pen(Color.Red)
g.DrawEllipse(stift, new Rectangle(10,10,20,20))

Dies malt einen roten Kreis mit Pinselstärke 1 Pixel und Durchmesser 10 Pixel mit dem Linken oberen Punkt 10,10. Pens ermöglichen auch Strichmuster, Farben und Strichstärken zu verändern.

um etwas zu füllen brauchst du Brushes. Der einfachste ist der SolidBrush - also eine Einfarbenfüllung. Der gleiche Kreis von oben, aber ausgefüllt:
Code:
Dim eimer as new System.Drawing.SolidBrush(Color.Red)
g.fillEllipse(eimer, new Rectangle(10,10,20,20))

für deine Grafik wirst du noch andere Braushes brauchen, nähmlich solche, die einen Verlauf erzeugen. Also z.b. LinearGradientBrush oder PathGradientBrush. Schau dir am besten mal in der MSDN dazu die Artikel zu Graphics und den Brushes an:
http://msdn.microsoft.com/de-de/library/system.drawing.graphics_members.aspx
http://msdn.microsoft.com/de-de/library/system.drawing.brush.aspx
 
Danke!

Soweit konnte ich die Grafik schon teilweiße (als WPF-Projekte) nachbilden, allerdings bekomm ich diese licht-reflektion nicht hin. Vermutlicherweiße braucht man dafür keine festvorgegebene geometrische Figur sondern ein Polygon welches man nur noch richtig hinbiegen muss. Nur, wie lässt sich sowas realisieren?

Sobald ich morgen auf arbeit bin werde ich mal meinen aktuellen Code posten damit man auch etwas hat worauf man aufbauen kann.
 
Zuletzt bearbeitet:
Da die Grafik ja eine konstante ist, bietet sich die Methode Graphics.FillPolygon an. Diese bietet 4 Überladungen:
FillPolygon(Brush, Point())
FillPolygon(Brush, PointF())
FillPolygon(Brush, Point(), FillMode)
FillPolygon(Brush, PointF(), FillMode)

1 und 2 sowie 3 und 4 sind quasi das gleich - nur übergibtst du einmal einen Point-Array, das andere mal ein PointF()-Array (einmal Ganzzahlige Daten, einmal Gebrochene Zahlen)

ein Beispiel:

Code:
Dim poly() as Point= {new Point(10,10), New Point(30,15), New Point(20,30)}
g.FillPolygon(new SolidBrush(Color.Red), poly)

edit:
Die kontur eines Piolygons zeichnet man natürlich mit Graphics.DrawPolygon, weiter Grafikfunktionen:
http://msdn.microsoft.com/de-de/library/system.drawing.graphics_members.aspx

Für solche polygone gelten dieselben Regeln wie für die Vorgegebenen Formen: Auch hier kann man mit anderen Bushes innere Verläufe erzeugen und mit Pens die Kontur nachzeichen. Achte darauf, dass die Polygone als geschlossene Form interpretiert werden. Der Letze Punkt wird also stets mit dem ersten Verbunden - anders als bei Graphics.DrawLines

edit:
Kontur nachzeichnen geht natürlich mit Graphics.DrawPolygon.
Weiter Grafikfunktionen: http://msdn.microsoft.com/de-de/library/system.drawing.graphics_members.aspx
 
Zuletzt bearbeitet:
Soweit hab ich mich schon an das Polygon rangewagt. Das ganze wird nur kein perfekter "Kreis" besser gesagt ist das ganze noch SEHR ausbaufähig.

Ich hoffe mir kann jemand Tipps und Kniffe zur Verbesserung flüstern (schreiben geht natürlich auch ;) )

Hier gibt es meinen aktuellen VB/XAML-Code:

VB:
Code:
Imports System.Windows.Media
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports RadialGradientBrush = System.Windows.Media.RadialGradientBrush
Imports GradientStop = System.Windows.Media.GradientStop
Imports Color = System.Windows.Media.Color


Class MainWindow
    Public Sub New()

        ' Dieser Aufruf ist für den Designer erforderlich.
        InitializeComponent()

        ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.

        Dim MainEllipseGradient = New RadialGradientBrush()


        MainEllipseGradient.GradientOrigin = New System.Windows.Point(0.77F, 0.77F)
        MainEllipseGradient.Center = New System.Windows.Point(0.57F, 0.55F)
        MainEllipseGradient.RadiusX = 0.55F
        MainEllipseGradient.RadiusY = 0.55F
        MainEllipseGradient.GradientStops.Add(New GradientStop(Color.FromArgb(&HFF, &HFF, &HFF, &HFF), 0.12F))
        MainEllipseGradient.GradientStops.Add(New GradientStop(Color.FromArgb(&HFF, &H99, &HFF, &H99), 0.25F))
        MainEllipseGradient.GradientStops.Add(New GradientStop(Color.FromArgb(&HFF, &H0, &HA0, &H0), 0.75F))

        MainEllipseGradient.Freeze()
        MainEllipse.Fill = MainEllipseGradient


        Dim MainEllipseStrokeGradient = New System.Windows.Media.LinearGradientBrush

        MainEllipseStrokeGradient.StartPoint = New System.Windows.Point(0.0F, 0.0F)
        MainEllipseStrokeGradient.EndPoint = New System.Windows.Point(1.0F, 1.0F)
        MainEllipseStrokeGradient.GradientStops.Add(New GradientStop(Color.FromArgb(&HFF, &HFF, &HFF, &HFF), 1.0F))
        MainEllipseStrokeGradient.GradientStops.Add(New GradientStop(Color.FromArgb(&HFF, &H40, &H40, &H40), 0.5F))

        MainEllipse.Stroke = MainEllipseStrokeGradient

    End Sub
End Class
XAML:
Code:
<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid Name="MyGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="6*" />
            <RowDefinition Height="305*" />
        </Grid.RowDefinitions>
        <Ellipse Height="28" HorizontalAlignment="Left" Name="MainEllipse" Stroke="Black" VerticalAlignment="Top" Width="28" Grid.RowSpan="2"/>
        <Polygon HorizontalAlignment="Left" Name="Poly" Stroke="Black" VerticalAlignment="Top" Points="1,14 6.5,14 6.54,13 6.66,12 6.85,11 7.14,10 7.7,9 8.47,8 9.45,7 10.65,6 11.12,5 12.19,4 14,6.5 14,1 13,1 12,1.16 11,1.32 10,1.64 9,1.99 8,2.46 7,3.02 5.69,4 4.62,5 3.75,6 3.05,7 2.47,8 2.0,9 1.64,10 1.35,11 1.16,12 1.04,13" Fill="#FFFF0303" OpacityMask="{x:Null}" Grid.RowSpan="2" StrokeThickness="0.0001" />
        
    </Grid>
</Window>
 
Zurück
Oben