Du bist nicht angemeldet.

martinustreveri

Deine Mama.

  • »martinustreveri« ist männlich
  • »martinustreveri« ist der Autor dieses Themas

Beiträge: 363

Dabei seit: 26. November 2008

Wohnort: Zuhause (:

Hilfreich-Bewertungen: 17

  • Private Nachricht senden

1

Freitag, 9. April 2010, 21:34

Einstieg in GDI+ (Ausführlich)

Zitat

Ich hab neue Wasserfarben!
Oh.. Ich male immernoch mit GDI+
Hey,

ich habe vor ein paar Wochen angefangen, ein wenig mit GDI+ zu spielen und wollte euch nun auch mal den Einstieg mit diesem kleinen Tutorial vereinfachen =)


Aufbau

  1. Einfache Linien >>malen<<
  2. Ein Rechteck und weitere geometrische Formen
  3. Abschluss

Teil 1: Einache Linien >>malen<<

Man kennt es ja von den Grafikbibliotheken in z.B. C++:
alles ist aufwendig, schwer zu verstehen und braucht folglich viel Zeit.

Nicht so in VB.NET mit GDI+!

Ich werde zuerst mal den ganzen Code posten und ihn dann in Teilen erklären.

Visual Basic Quellcode

1
2
3
4
5
6
Dim graphic As Graphics
Dim p As Pen

graphic = Me.CreateGraphics()
p = New Pen(System.Drawing.Color.Black, 10)
grahic.DrawLine(p, 0, 0, Me.Width, Me.Height)



Nun zur Erklärung

Visual Basic Quellcode

1
2
Dim graphic As Graphics
Dim p As Pen

Sind erstmal Variablen, die wir zum Zeichnen brauchen.
Das Pen-Objekt sollte sich von selbst erklären, es beinhaltet später die Eigenschaften des >>Stiftes<<, mit dem wir zeichnen.

Das Graphics-Object stellt u.A. die Funktionen bereit, die wir zum Zeichnen brauchen.

Visual Basic Quellcode

1
graphic = Me.CreateGraphics()

Mit Me.CreateGraphics() stellt sich die Form als >>Papier<< für unsere Zeichnung zur verfügung.

Visual Basic Quellcode

1
p = New Pen(System.Drawing.Color.Black, 10)

Wir >>suchen uns einen Stift aus<< , in unserem Fall soll es ein 10 Pixel (ja, hier wird in Pixeln gerechnet) großer, schwarzer Buntstift sein.


Visual Basic Quellcode

1
graphic.DrawLine(p, 0, 0, Me.Width, Me.Height)

Wir fangen an zu zeichnen. Wir wollen einen Strich von dem Punkt a(0|0) nach b(Me.Width|Me.Height)(z.B. b(100|100)) mit dem vorhin gewählten Stift(p) zeichnen.

Die Punkte sind in einem gedachten Koordinatensystem(von links oben ausgehend.).

ACHTUNG: Man kann eine "Malaktion" nicht durch den MyBase.Load-Handler auslösen!!

Teil 2: Ein Rechteck und weitere geometrische Formen

Visual Basic Quellcode

1
2
3
4
Dim graphic As Graphics = Me.CreateGraphics
Dim pen As New Pen(Color.Black, 1)
Dim rec As New Rectangle(1, 1, 100, 100)
graphic.DrawRectangle(pen, rec)


Visual Basic Quellcode

1
2
Dim graphic As Graphics = Me.CreateGraphics
Dim pen As New  Pen(Color.Black, 1)

Gleiches verfahren wie vorher, nur kürzer.

Visual Basic Quellcode

1
Dim rec As New Rectangle(1, 1, 100, 100)

Wir erzeugen ein vorerst nicht sichtbares Rechteck, welches wir später am Punkt p(0|0) mit Höhe 100 Pixel und Breite 100 Pixel zeichnen möchten

Visual Basic Quellcode

1
graphic.DrawRectangle(pen, rec)

Das sollte sich wohl von selbst erklären.
Ja, die Graphics-Instanz stellt für jede geom.(nicht-dreidimensionale, afaik) Form eine draw-Funktion bereit.

Unten auf der Seite gibt es eine schöne Tabelle an Funktionen.

Teil 3: Abschluss

So, ich habe hier noch eine kleine Funktion für ein Gitter mit 5² Pixeln unterteilung geschrieben ;)

Visual Basic Quellcode

1
2
3
4
5
6
7
8
9
10
11
Dim graphic As Graphics = Me.CreateGraphics
    	Dim pen As New Pen(Color.Black, 1)

    	For i As Integer = 0 To Me.Width
        	graphic.DrawLine(pen, i, 0, i, Me.Height)
        	i += 4
    	Next
    	For i As Integer = 0 To Me.Height
        	graphic.DrawLine(pen, 0, i, Me.Width, i)
        	i += 4
    	Next


Hoffe ihr konntet was lernen =)



lg.

PS: Ich weiß, es ist nichts besonderes für die, die es können, aber für Leute die das nicht können... :)
~Edit: Wenn ihr das anseht, dann bitte auch Feedback abgeben..
"Five exclamation marks, the sure sign of an insane mind."

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »martinustreveri« (9. April 2010, 23:31)


Es haben bereits 8 registrierte Benutzer diesen Beitrag als hilfreich eingestuft.

Benutzer, die diesen Beitrag hilfreich fanden:

Homer, Lockerzzz, Florian, tybae, Chriis, Seppi123, Roland K., domipoppe

progglord

Registrierter Benutzer

  • »progglord« ist männlich

Beiträge: 902

Dabei seit: 10. April 2009

Wohnort: Holzminden

Hilfreich-Bewertungen: 22

  • Private Nachricht senden

2

Freitag, 9. April 2010, 22:52

ACHTUNG: Man kann eine "Malaktion" nicht durch den MyBase.Load-Handler auslösen!!

Logisch, wenn die Form noch nicht geladen ist und nichts angezeigt wird, kann man auch nicht drauf zeichnen. Hier schafft entweder das Paint Event oder das Shown Event aushilfe.

Visual Basic Quellcode

1
Dim rec As New Rectangle(1, 1, 100, 100)


Wir erzeugen ein vorerst nicht sichtbares Rechteck, welches wir später am Punkt p(0|0) mit Höhe 100 Pixel und Breite 100 Pixel zeichnen möchten

Wenn du das Rechteck am Punkt p(1|1) definierst, wird es aber nicht auf Punkt p(0|0) sondern auch auf p(1|1) gezeichnet ;).

Visual Basic Quellcode

1
2
3
4
5
6
7
8
9
10
Dim graphic As Graphics = Me.CreateGraphics 
Dim pen As New Pen(Color.Black, 1) 
For i As Integer = 0 To Me.Width 
    graphic.DrawLine(pen, i, 0, i, Me.Height) 
    i += 4 
Next 
For i As Integer = 0 To Me.Height 
    graphic.DrawLine(pen, 0, i, Me.Width, i) 
    i += 4 
Next

Hier sollte man für i += 4 in der For Schleife einen Step +4 angeben ;).

Nochmal um das Tutorial etwas zu erweitern, wie man ein Graphics Object bekommt.
Es wurde ja schon gesagt wie von der Form (mit Me.CreateGraphics()), aber es ist nat. auch möglich auf Bilder zu zeichnen. Das geht dann mit Graphics.FromImage(bild), wobei bild vom Typ Image sein sollte.

Dann noch das Paint Event was ganz wichtig ist. Es wird immer ausgelöst wenn die Form erzeugt wird, wenn sie vergrößert wird und auch wenn die Form neugezeichnet wird.
Dort holt man sich das Graphics Object aus den EventArgs. Also:

Visual Basic Quellcode

1
Dim g As Graphics = e.Graphics

Man kann das Paint Event auch selbst auslösen, so:

Visual Basic Quellcode

1
con.Invalidate()
wobei "con" nat. für ein Control oder eine Form steht.
Man kann auch nur einen bestimmten Bereich neuzeichnen so:

Visual Basic Quellcode

1
con.Invalidate(New Region(New Rectangle(x, y, Weite, Höhe))

DragonSam

Registrierter Benutzer

  • »DragonSam« ist männlich

Beiträge: 149

Dabei seit: 28. Mai 2009

  • Private Nachricht senden

3

Samstag, 10. April 2010, 00:01

Also ich habe das ganze jetzt einfach mal testweise kopiert und in eine Subroutine gesetzt zu der die Variablen übergeben werden, aber es wird nichts gezeichnet.

 Hier klicken für weitere Informationen

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D

Public Class Form1
	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    	Me.Size = New Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
    	Fullscreen.Size = New Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
    	Auflösung.Text = Screen.PrimaryScreen.Bounds.Width & "x" & Screen.PrimaryScreen.Bounds.Height
    	Select Case Screen.PrimaryScreen.Bounds.Width / Screen.PrimaryScreen.Bounds.Height
        	Case 16 / 9
            	Auflösung.Text += " (16:9)"
        	Case 16 / 10
            	Auflösung.Text += " (16:10)"
        	Case 4 / 3
            	Auflösung.Text += " (4:3)"
    	End Select
	End Sub

	Private Sub Form1_Shown(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown
    	Const HKEY_LOCAL_MACHINE = &H80000002

    	Dim objRegistry As Object = GetObject("winmgmts:\\.\root\default:StdRegProv")
    	Dim strValue As String = ""
    	Dim strVersion As String = ""
    	Dim strKeyPath As String = "Software\Microsoft\DirectX"
    	Dim strValueName As String = "Version"

    	objRegistry.GetStringValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue)

    	Select Case strValue
        	Case "4.02.0095"
            	strVersion = "1.0"
        	Case "4.03.00.1096"
            	strVersion = "2.0a"
        	Case "4.04.00.0068"
            	strVersion = "3.0"
        	Case "4.04.00.0069"
            	strVersion = "3.0"
        	Case "4.04.00.0070"
            	strVersion = "3.0a"
        	Case "4.05.00.0155"
            	strVersion = "5.0"
        	Case "4.05.01.1600"
            	strVersion = "5.2"
        	Case "4.05.01.1998"
            	strVersion = "5.2"
        	Case "4.06.00.0318"
            	strVersion = "6.0"
        	Case "4.06.02.0436"
            	strVersion = "6.1"
        	Case "4.06.03.0518"
            	strVersion = "6.1a"
        	Case "4.07.00.0700"
            	strVersion = "7.0"
        	Case "4.07.00.0716"
            	strVersion = "7.0a"
        	Case "4.07.01.3000"
            	strVersion = "7.1"
        	Case "4.08.00.0400"
            	strVersion = "8.0"
        	Case "4.08.01.0810"
            	strVersion = "8.1"
        	Case "4.08.01.0881"
            	strVersion = "8.1"
        	Case "4.08.01.0901"
            	strVersion = "8.1a"
        	Case "4.08.02.0134"
            	strVersion = "8.2"
        	Case "4.09.00.0900"
            	strVersion = "9.0"
        	Case "4.09.00.0901"
            	strVersion = "9.0a"
        	Case "4.09.00.0902"
            	strVersion = "9.0b"
        	Case "4.09.00.0903"
            	strVersion = "9.0c"
        	Case "4.09.00.0904"
            	strVersion = "9.0c"
        	Case "4.09.0000.0904"
            	strVersion = "9.28"
        	Case "6.00.6000.16386"
            	strVersion = "10"
        	Case "6.00.6001.18000"
            	strVersion = "10.1"
        	Case "6.01.7000.0000"
            	strVersion = "11"
        	Case Else
            	strVersion = "nicht bekannt"
    	End Select


    	Auflösung.Text += "  DirectX-Version: " & strVersion & " (" & strValue & ")"
    	Box_zeichnen(20, 20, 100, 100)

	End Sub

	Private Sub Fullscreen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Fullscreen.Click
    	Close()
	End Sub

	Private Sub Box_zeichnen(ByVal bx, ByVal by, ByVal bwidth, ByVal bheight)
    	Dim graphic As Graphics = Me.CreateGraphics
    	Dim pen As New Pen(System.Drawing.Color.Black, 1)
    	Dim rec As New Rectangle(bx, by, bwidth, bheight)
    	graphic.DrawRectangle(pen, rec)
	End Sub
End Class


Mangafreak1995

Anwendungsentwickler

  • »Mangafreak1995« ist männlich

Beiträge: 1 670

Dabei seit: 16. August 2009

Wohnort: /home/usr/

Hilfreich-Bewertungen: 175

  • Private Nachricht senden

4

Samstag, 10. April 2010, 00:24

du hast grad DX mit GDI vermischt ... es kann sein dass dein DX dein GDI übermalt

Load-soft.ch.vu

Mag Algorithmen :)

  • »Load-soft.ch.vu« ist männlich

Beiträge: 988

Dabei seit: 30. Oktober 2009

Wohnort: Berlin

Frühere Benutzernamen: Confix.npage.de

Hilfreich-Bewertungen: 2

  • Private Nachricht senden

5

Samstag, 10. April 2010, 11:00

Also ich habe das ganze jetzt einfach mal testweise kopiert und in eine Subroutine gesetzt zu der die Variablen übergeben werden, aber es wird nichts gezeichnet.

 Hier klicken für weitere Informationen

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D

Public Class Form1
	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    	Me.Size = New Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
    	Fullscreen.Size = New Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
    	Auflösung.Text = Screen.PrimaryScreen.Bounds.Width & "x" & Screen.PrimaryScreen.Bounds.Height
    	Select Case Screen.PrimaryScreen.Bounds.Width / Screen.PrimaryScreen.Bounds.Height
        	Case 16 / 9
            	Auflösung.Text += " (16:9)"
        	Case 16 / 10
            	Auflösung.Text += " (16:10)"
        	Case 4 / 3
            	Auflösung.Text += " (4:3)"
    	End Select
	End Sub

	Private Sub Form1_Shown(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown
    	Const HKEY_LOCAL_MACHINE = &H80000002

    	Dim objRegistry As Object = GetObject("winmgmts:\\.\root\default:StdRegProv")
    	Dim strValue As String = ""
    	Dim strVersion As String = ""
    	Dim strKeyPath As String = "Software\Microsoft\DirectX"
    	Dim strValueName As String = "Version"

    	objRegistry.GetStringValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue)

    	Select Case strValue
        	Case "4.02.0095"
            	strVersion = "1.0"
        	Case "4.03.00.1096"
            	strVersion = "2.0a"
        	Case "4.04.00.0068"
            	strVersion = "3.0"
        	Case "4.04.00.0069"
            	strVersion = "3.0"
        	Case "4.04.00.0070"
            	strVersion = "3.0a"
        	Case "4.05.00.0155"
            	strVersion = "5.0"
        	Case "4.05.01.1600"
            	strVersion = "5.2"
        	Case "4.05.01.1998"
            	strVersion = "5.2"
        	Case "4.06.00.0318"
            	strVersion = "6.0"
        	Case "4.06.02.0436"
            	strVersion = "6.1"
        	Case "4.06.03.0518"
            	strVersion = "6.1a"
        	Case "4.07.00.0700"
            	strVersion = "7.0"
        	Case "4.07.00.0716"
            	strVersion = "7.0a"
        	Case "4.07.01.3000"
            	strVersion = "7.1"
        	Case "4.08.00.0400"
            	strVersion = "8.0"
        	Case "4.08.01.0810"
            	strVersion = "8.1"
        	Case "4.08.01.0881"
            	strVersion = "8.1"
        	Case "4.08.01.0901"
            	strVersion = "8.1a"
        	Case "4.08.02.0134"
            	strVersion = "8.2"
        	Case "4.09.00.0900"
            	strVersion = "9.0"
        	Case "4.09.00.0901"
            	strVersion = "9.0a"
        	Case "4.09.00.0902"
            	strVersion = "9.0b"
        	Case "4.09.00.0903"
            	strVersion = "9.0c"
        	Case "4.09.00.0904"
            	strVersion = "9.0c"
        	Case "4.09.0000.0904"
            	strVersion = "9.28"
        	Case "6.00.6000.16386"
            	strVersion = "10"
        	Case "6.00.6001.18000"
            	strVersion = "10.1"
        	Case "6.01.7000.0000"
            	strVersion = "11"
        	Case Else
            	strVersion = "nicht bekannt"
    	End Select


    	Auflösung.Text += "  DirectX-Version: " & strVersion & " (" & strValue & ")"
    	Box_zeichnen(20, 20, 100, 100)

	End Sub

	Private Sub Fullscreen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Fullscreen.Click
    	Close()
	End Sub

	Private Sub Box_zeichnen(ByVal bx, ByVal by, ByVal bwidth, ByVal bheight)
    	Dim graphic As Graphics = Me.CreateGraphics
    	Dim pen As New Pen(System.Drawing.Color.Black, 1)
    	Dim rec As New Rectangle(bx, by, bwidth, bheight)
    	graphic.DrawRectangle(pen, rec)
	End Sub
End Class

Hi,
probiers mal mit graphics.flush / Me.refresh !

@Topic
Ich zeichne immer im Form_Load ohne probleme!
Mfg
Loadsoft
Falls dir geholfen wurde :thanks;

tobikubi

Registrierter Benutzer

  • »tobikubi« ist männlich

Beiträge: 1 374

Dabei seit: 20. Oktober 2007

Wohnort: Bottrop

  • Private Nachricht senden

6

Samstag, 10. April 2010, 11:16

eigentlich müsste man, wie schon in anderen Subs erwähnt, solche Sachen in paint ereignisse, da das paint der form die Sachen wieder überschreibt die einmalig gezeichnet wurden;)
wer Rechtschreibfehler findet, darf sie behalten,
my.working.area = "amd phenom 4x 3 Ghz, 8GB Ram, Gigabyte MA770-UD3, MSI n9800GT-MD1G

Eigenschaftseditor für Objekte
Fortschritt: 30%

DragonSam

Registrierter Benutzer

  • »DragonSam« ist männlich

Beiträge: 149

Dabei seit: 28. Mai 2009

  • Private Nachricht senden

7

Samstag, 10. April 2010, 18:29

probiers mal mit graphics.flush / Me.refresh !
Bei Me.Refresh ändert sich nichts und Graphics.Flush nimmt er nicht. Das gibt es nicht.

martinustreveri

Deine Mama.

  • »martinustreveri« ist männlich
  • »martinustreveri« ist der Autor dieses Themas

Beiträge: 363

Dabei seit: 26. November 2008

Wohnort: Zuhause (:

Hilfreich-Bewertungen: 17

  • Private Nachricht senden

8

Sonntag, 11. April 2010, 14:34

Ich denke er meinte, dass du die Funktion von dem Graphics-Objekt ausführen sollst.
Ist ja klar, wenn du kein Objekt namens Graphics hast (was ja nicht geht, da die Klasse ja so heißt..) wird auch nichts gehen.

Man kann übrigens auch ein sehr einfaches PingPong Spiel so schreiben(mit wenig Aufwand), man muss halt immer prüfen ob ob der Ball auf diese Bretterdinger kommt, wenn ja einfach im gespiegelten Winkel weitertitschen lassen, wenn doch einfach normal weiter..^^)

lg.
"Five exclamation marks, the sure sign of an insane mind."

SAR-71

Programmierer aus Leidenschaft

  • »SAR-71« ist männlich

Beiträge: 429

Dabei seit: 11. März 2009

Wohnort: Hamburg

Hilfreich-Bewertungen: 65

  • Private Nachricht senden

9

Samstag, 3. Juli 2010, 17:50

Kann man damit eig. auch Grafiken importieren (Und zwar, dass es nicht anfängt zu "laggen")?

Und wann gibt es eine Fortsetzung? :P






Mfg.
SAR

kevin89

Super Moderator

  • »kevin89« ist männlich

Beiträge: 3 881

Dabei seit: 16. April 2008

Hilfreich-Bewertungen: 155

  • Private Nachricht senden

10

Samstag, 3. Juli 2010, 18:11

DrawImage? btw: Noch nie was von BufferedGraphics gehört? oO

martinustreveri

Deine Mama.

  • »martinustreveri« ist männlich
  • »martinustreveri« ist der Autor dieses Themas

Beiträge: 363

Dabei seit: 26. November 2008

Wohnort: Zuhause (:

Hilfreich-Bewertungen: 17

  • Private Nachricht senden

11

Samstag, 3. Juli 2010, 21:05

Hey,

du könntest, neben BufferedGraphics, auch auf eine Bitmap (Objekt) zeichnen und diese dann auf den Bildschirm malen. (bzw neu laden).

lg.
"Five exclamation marks, the sure sign of an insane mind."

kevin89

Super Moderator

  • »kevin89« ist männlich

Beiträge: 3 881

Dabei seit: 16. April 2008

Hilfreich-Bewertungen: 155

  • Private Nachricht senden

12

Samstag, 3. Juli 2010, 21:19

Unperformant und unnötig speicherlastig.

Social Bookmarks