Benutzer mit den meisten Antworten
Ich würde gerne in der VB.Net Oberfläche einen GDI+ Loop als Gif Dateiformat speichern. Ist das möglich?

Frage
-
Hallo.
Ich studiere die GDI+ Möglichkeiten des VB.Net Programms. Es folgt ein kleiner Loop einer graphischen Ausgabe.
Imports System.Drawing.Drawing2D Public Class Form1 Dim WithEvents t As New Timer() With {.Interval = 50} Dim zweiPlusZwei As Boolean Dim startUndZiel As Integer Dim dieEins As Integer Dim minus As Integer Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load CenterToScreen() t.Start() DoubleBuffered = True zweiPlusZwei = True startUndZiel = 10 dieEins = 1 minus = 200 End Sub Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint ' Create a GraphicsPath object and add a rectangle to it. Dim myPath As New GraphicsPath Dim pathRect As New Rectangle(20, startUndZiel, 100, minus) ' falls minus ersetzt wird durch eine Zahl bewegt sich der Monolit so ist es nur eine optische Täuschung myPath.AddRectangle(pathRect) ' Draw the path to the screen. Dim myPen As New Pen(Color.Black, 2) e.Graphics.DrawPath(myPen, myPath) End Sub Private Sub t_Tick(sender As Object, e As EventArgs) Handles t.Tick If zweiPlusZwei = True Then If startUndZiel <= 128 Then startUndZiel += dieEins minus -= dieEins Else zweiPlusZwei = False End If End If If zweiPlusZwei = False Then If startUndZiel > 10 Then startUndZiel -= dieEins minus += dieEins Else zweiPlusZwei = True End If End If Refresh() End Sub End Class
Ich wünsche mir die graphische Darstellung gespeichert in einem Gif Dateiformat, so dass ich mir wenn ich die Gif Datei Doppelklicke nur die graphische Bewegung angezeigt wird. Es muss kein Doppelklick sein, das Gif Dateiformat kann auch mit dem Windows Programm Fotos abgespielt werden so das gespeicherte Bewegungen abspielbar sind. Wenn eine Speicherung der Ausgabe des VB.Net Programms möglich ist würde ich gerne Wissen wie das geht. Danke.
Antworten
-
Hallo Stefan Mihael Rihar,
wenn Du die Klasse AnimatedGifEncoder aus dem verlinkten Forumsbeitrag meiner ersten Antwort verwendest, könnte die Implementierung so aussehen:
Public Class Form1 Dim WithEvents t As New Timer() With {.Interval = 50} Dim blackPen As New Pen(Color.Black, 3) Dim zweiPlusZwei As Boolean Dim startUndZiel As Integer Dim dieEins As Integer Dim minus As Integer Dim Encoder1 As New AnimatedGifEncoder Public Property MetadataComment As List(Of String) = New List(Of String) Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None CenterToScreen() t.Start() DoubleBuffered = True zweiPlusZwei = True startUndZiel = 10 dieEins = 1 minus = 200 End Sub Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint DrawRectangleRectangle(e) End Sub Private Sub t_Tick(sender As Object, e As EventArgs) Handles t.Tick If zweiPlusZwei = True Then If startUndZiel <= 128 Then startUndZiel += dieEins minus -= dieEins Else zweiPlusZwei = False End If End If If zweiPlusZwei = False Then If startUndZiel > 10 Then startUndZiel -= dieEins minus += dieEins Else zweiPlusZwei = True End If End If Refresh() castleGrayscul(e) End Sub Public Sub SaveImage(filename As String) Dim FS As New IO.FileStream(filename, IO.FileMode.Create) Encoder1.FrameRate = t.Interval Encoder1.MetadataString = MetadataComment Encoder1.Repeat = True Encoder1.Save(FS) FS.Flush() FS.Close() End Sub Public Sub DrawRectangleRectangle(ByVal e As PaintEventArgs) e.Graphics.DrawRectangle(blackPen, 20, startUndZiel, 100, minus) End Sub Sub castleGrayscul(ByVal e As EventArgs) 'castleGrayscul versus Monkeyisland. . . Dim bmp As New Bitmap(Width - 16, Height - 39) DrawToBitmap(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height)) Encoder1.AddFrame(bmp) bmp.Dispose() End Sub Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed SaveImage("C:\Temp\Probst.gif") End Sub End Class
Bei den Referenzen müssen ggfls. Assemblies hinzugefügt werden, die von AnimatedGifEncoder verwendet werden (PresentationCore).
Das Ergebnis sieht dann so aus:
- Gruß Florian
- Als Antwort vorgeschlagen Florian Haupt Freitag, 31. August 2018 07:09
- Als Antwort markiert Stefan Mihael Rihar Mittwoch, 5. September 2018 16:00
-
Du kannst das Speichern direkt unter t.Stop aufrufen, ggfls. auch gleich die Form schließen.
- Gruß Florian
- Als Antwort vorgeschlagen Florian Haupt Freitag, 31. August 2018 07:10
- Als Antwort markiert Stefan Mihael Rihar Mittwoch, 5. September 2018 16:08
Alle Antworten
-
Hallo Stefan Mihael Rihar,
es ist möglich, aber der Encoder muss, so wie hier nachzulesen "Animated GIF encoder .NET" erweitert werden, um den GIF89a Teil - Code für den Encoder und Anwendungsbeispiel sind unter dem Link zu finden.
Viel Erfolg!
- Gruß Florian
- Bearbeitet Florian Haupt Freitag, 10. August 2018 07:37 Tippfehler
- Als Antwort vorgeschlagen Florian Haupt Freitag, 31. August 2018 07:09
-
Verstehe ich gerade nicht, wo da jetzt das Problem liegt. Deine Form ist ein Control und daher kannst Du nach jedem Paint oder am Ende einfach DrawToBitmap aufrufen um deine Form in ein Bitmap zu zeichnen, dieses dann als Frame in dein GIF, fertig. Du kannst natürlich auch direkt in deine GIF Frames Zeichnen und dir damit die Form vollständig sparen.
- Gruß Florian
-
Ich habe noch nicht den Befehl DrawToBitmap aufgerufen. Wird noch etwas Arbeit notwendig sein um das Thema verstehen zu lernen. Direkt in ein GIF Frames zeichnen scheint einfach zu sein doch habe ich auch dazu keinen Begriff. Ich werde mich auch weiterhin bemühen meine Projektarbeiten nicht woanders abzuladen nur manchmal brauch ich einige Hinweise.
Mit freundlichen Grüßen
Stefan
- Bearbeitet Stefan Mihael Rihar Sonntag, 12. August 2018 13:38
-
Hallo Stefan Mihael Rihar,
die Dokumentation zu Control.DrawToBitmap. Weiterhin benötigst Du die Größe, z. B. über die Size-Eigenschaft (bzw. Width, Height).
Das gilt dann allgemein für jedes Control:
- Bitmap in der Größe des Controls anlegen
- Das Control mit DrawToBitmap ins Bitmap zeichnen lassen
Bsp.:
Dim bmp as New Bitmap(meinControl.Width, meinControl.Height) meinControl.DrawToBitmap(bmp, New Rectangle(0,0, bmp.Width, bmp.Height))
Das bmp kann dann in den Frame gespeichert werden.
- Gruß Florian
-
Mein Vb.Net Studium ohne Universitätszugang wird wohl eine Zeit dauern. Die Frage an der ich mich versuche ist wie ich mit dem Beispiel
Public Class Form1 Dim bmp As New Bitmap(Me.Width, Me.Height) Sub kleinerStein(ByVal a As EventArgs) 'castleGrayscul versus Monkeyisland. . . Me.DrawToBitmap(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height)) End Sub Private Sub Form1_Load(sender As Object, a As System.EventArgs) Handles Me.Load kleinerStein(a) End Sub End Class
verstehen soll was ich mit meiner Kunst in den Frame speichern soll? Ich übe jeden Tag von Anfang an, falls sich das so bezeichnen lässt Vb.Net in mein Leben zu integrieren. Leider mühsam aber es geht. Das ist wichtig. Und ich würde gerne Wissen ist der Befehl DrawToBitmap ein Zwischenspeicher den ich nicht zu lesen weiß? Sichtbar machen ist für mich sehr wichtig.
Mit freundlichen Grüßen
Stefan
-
Hallo Stefan Mihael Rihar.
DrawToBitmap ist eine Methode der Klasse Control (Namespace: System.Windows.Forms), welche zwei Parameter hat und keinen Rückgabewert. Der erste Parameter (bitmap) gibt ein Object der Klasse Bitmap (Namespace: System.Drawing) an, auf dem gezeichnet werden soll. Der zweite Parameter (targetBounds) gibt ein Object der Struktur Rectangle (Namespace: System.Drawing) an, welches einen rechteckigen Bereich beschreibt, in dessen Grenzen gezeichnet werden soll.
Nach dem Aufruf DrawToBitmap wurde in deine Bitmap Variable gezeichnet, die du als Parameter übergeben hast, dieses enthält nun ein Abbild deines Controls, zum Zeitpunkt des Aufrufs. Das Bitmap kann dann auf einem Anzeigegerät ausgegeben werden (Bildschirm, Drucker, ...) oder auch gespeichert (Bitmap hat dafür eine Methode Save) werden.
- Gruß Florian
-
Hallo, da Du ein Paint Event bereits behandelst
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
weißt Du bereits wo das Zeichnen stattfindet, in diesem Paint Event.
Es ist natürlich nicht besonders Sinnvoll das Bitmap, welches die aktuelle Form enthält, in dieser auszugeben, aber das grundsätzliche Verfahren zum Anzeigen eines Bitmaps auf dem Bildschirm sollte damit ausreichend illustriert sein, hier unter Verwendung von DrawImage:
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint ... e.Graphics.DrawImage(bmp, 0, 0) End Sub
- Gruß Florian
-
Meine schwache Ausdrucksweise in der Programmiersprache VB.Net ist eine Krücke. Ich habe einen Code aus verschiedenen Quellen zusammengebastelt mit dem ich wennmöglich weiter suchen kann zu verstehen was ich noch immer nicht kann.
Imports System.Drawing.Drawing2D Public Class Form1 Dim WithEvents t As New Timer() With {.Interval = 50} Dim bmp As New Bitmap(Me.Width - 16, Me.Height - 39) Dim blackPen As New Pen(Color.Black, 3) Dim zweiPlusZwei As Boolean Dim startUndZiel As Integer Dim dieEins As Integer Dim minus As Integer Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None CenterToScreen() t.Start() DoubleBuffered = True zweiPlusZwei = True startUndZiel = 10 dieEins = 1 minus = 200 End Sub Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint DrawRectangleRectangle(e) End Sub Private Sub t_Tick(sender As Object, e As EventArgs) Handles t.Tick If zweiPlusZwei = True Then If startUndZiel <= 128 Then startUndZiel += dieEins minus -= dieEins Else zweiPlusZwei = False End If End If If zweiPlusZwei = False Then If startUndZiel > 10 Then startUndZiel -= dieEins minus += dieEins Else zweiPlusZwei = True End If End If Refresh() End Sub Public Sub SaveImage(filename As String, image As Image) Dim path As String = System.IO.Path.Combine(My.Application.Info.DirectoryPath, filename & ".Bmp") Dim mySource As New Bitmap(image.Width, image.Height) Dim grfx As Graphics = Graphics.FromImage(mySource) grfx.DrawImageUnscaled(image, Point.Empty) grfx.Dispose() mySource.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp) mySource.Dispose() End Sub Public Sub DrawRectangleRectangle(ByVal e As PaintEventArgs) e.Graphics.DrawRectangle(blackPen, 20, startUndZiel, 100, minus) castleGrayscul(e) End Sub Sub castleGrayscul(ByVal e As EventArgs) 'castleGrayscul versus Monkeyisland. . . Me.DrawToBitmap(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height)) SaveImage("C:\Temp\Probst.bmp", bmp) End Sub End Class
Zwei Probleme habe ich weiterhin. Das erste ist noch immer das Hauptthema. Ich kann nun von der Sequenz immer das letzte Bild speichern aber nicht die ganze Sequenz in einer Gif Datei. Das zweite ist wenn ich Sub castleGrayscul verwende dann ist der Ablauf des Loops nicht mehr im flüssigen Interval = 50. Die Spurensuche geht weiter. . .Mit freundlichen Grüßen
Stefan
- Bearbeitet Stefan Mihael Rihar Mittwoch, 22. August 2018 17:54 Grammatik
-
Hallo Stefan Mihael Rihar,
wenn Du die Klasse AnimatedGifEncoder aus dem verlinkten Forumsbeitrag meiner ersten Antwort verwendest, könnte die Implementierung so aussehen:
Public Class Form1 Dim WithEvents t As New Timer() With {.Interval = 50} Dim blackPen As New Pen(Color.Black, 3) Dim zweiPlusZwei As Boolean Dim startUndZiel As Integer Dim dieEins As Integer Dim minus As Integer Dim Encoder1 As New AnimatedGifEncoder Public Property MetadataComment As List(Of String) = New List(Of String) Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None CenterToScreen() t.Start() DoubleBuffered = True zweiPlusZwei = True startUndZiel = 10 dieEins = 1 minus = 200 End Sub Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint DrawRectangleRectangle(e) End Sub Private Sub t_Tick(sender As Object, e As EventArgs) Handles t.Tick If zweiPlusZwei = True Then If startUndZiel <= 128 Then startUndZiel += dieEins minus -= dieEins Else zweiPlusZwei = False End If End If If zweiPlusZwei = False Then If startUndZiel > 10 Then startUndZiel -= dieEins minus += dieEins Else zweiPlusZwei = True End If End If Refresh() castleGrayscul(e) End Sub Public Sub SaveImage(filename As String) Dim FS As New IO.FileStream(filename, IO.FileMode.Create) Encoder1.FrameRate = t.Interval Encoder1.MetadataString = MetadataComment Encoder1.Repeat = True Encoder1.Save(FS) FS.Flush() FS.Close() End Sub Public Sub DrawRectangleRectangle(ByVal e As PaintEventArgs) e.Graphics.DrawRectangle(blackPen, 20, startUndZiel, 100, minus) End Sub Sub castleGrayscul(ByVal e As EventArgs) 'castleGrayscul versus Monkeyisland. . . Dim bmp As New Bitmap(Width - 16, Height - 39) DrawToBitmap(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height)) Encoder1.AddFrame(bmp) bmp.Dispose() End Sub Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed SaveImage("C:\Temp\Probst.gif") End Sub End Class
Bei den Referenzen müssen ggfls. Assemblies hinzugefügt werden, die von AnimatedGifEncoder verwendet werden (PresentationCore).
Das Ergebnis sieht dann so aus:
- Gruß Florian
- Als Antwort vorgeschlagen Florian Haupt Freitag, 31. August 2018 07:09
- Als Antwort markiert Stefan Mihael Rihar Mittwoch, 5. September 2018 16:00
-
Ja, Perfekt. Du hast das Ziel erreicht. Ich habe noch eine abschließende Bitte zu diesem Thema. Ich würde gerne die Gif Animation so speichern, dass der Anfangspunkt genau mit demselben Endpunkt gespeichert wird. Wenn die Animation im Kreis läuft es keinen Unterschied zwischen Anfangs- und Endpunkt gibt.
Mit freundlichen Grüßen
Stefan
-
Ich habe schon eine Möglichkeit gefunden.
Dim counter As Integer Dim search As New Label() Sub Form1_Load(. . .) . . . counter = 1 End Sub Sub Form1_Paint(. . .) search.Size = New System.Drawing.Size(25, 13) search.Location = New System.Drawing.Point(237, 5) search.Text = counter Me.Controls.Add(search) . . . End Sub Sub t_Tick(. . .) . . . 'If zweiPlusZwei = False Then ' If startUndZiel > 10 Then ' startUndZiel -= dieEins ' minus += dieEins ' Else ' zweiPlusZwei = True ' End If counter += 1 'End If If counter = 121 Then t.Stop() End If 'Refresh() . . . End Sub
Doch möglicherweise gibt es eine elegantere Lösung die ich in meinem Arbeitsfieber nicht erkennen konnte. Das Programm mit Alt+F4 Tastenkombination beenden und nicht nur den Compiler beenden Knopf verwenden sonst wird die Arbeit Probst.gif nicht gespeichert.
-
Du kannst das Speichern direkt unter t.Stop aufrufen, ggfls. auch gleich die Form schließen.
- Gruß Florian
- Als Antwort vorgeschlagen Florian Haupt Freitag, 31. August 2018 07:10
- Als Antwort markiert Stefan Mihael Rihar Mittwoch, 5. September 2018 16:08
-
Auf jeden Fall geht meine Reise hier zu Ende. Ich hoffe, dass ich jetzt nur noch kreative Animationen schreiben lerne und den technischen Studienteil auf später verschieben kann. Du hast mir mindestens 11 Millionen Lichtjahre Arbeit erspart.
Vielen Dank
Stefan
p.s.: Da ich meine Frage auch auf vb-paradise.de online gestellt habe und du die Antwort geschrieben hast würde ich gerne deinen Namen dort zitieren (mit der Antwort), ist das möglich?
-
Auf jeden Fall geht meine Reise hier zu Ende.
...
Freut mich, dass es dich weiter gebracht hat.
p.s.: Da ich meine Frage auch auf vb-paradise.de online gestellt habe und du die Antwort geschrieben hast würde ich gerne deinen Namen dort zitieren (mit der Antwort), ist das möglich?
Da habe ich nichts dagegen.
- Gruß Florian
-
Danke.
Mit freundlichen Grüßen
Stefan
- Bearbeitet Stefan Mihael Rihar Freitag, 31. August 2018 11:34
-
Hallo Stefan,
Wenn Deine Frage beantwortet wurde, wäre es nett von Dir, wenn Du die Beiträge, die Dich weitergebracht haben, als Antwort markieren würdest. Ich verweise Dich auf die Forenregeln:
· Lösungsbeiträge als “Die Antwort“ markieren
Bitte markieren Sie den Beitrag, der zur Lösung geführt hat, als "Die Antwort". Durch Bewerten eines Beitrags als "Die Antwort" können andere Teilnehmer die Lösung schneller finden. Außerdem können Sie dem Benutzer, der die Antwort eingereicht hat, für seinen Beitrag danken und zur Steigerung der Antwortqualität in der Diskussionsgruppe beitragen.
[Quelle: Forenregeln]Gruß,
Dimitar
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.
- Bearbeitet Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 5. September 2018 10:12