Animierte GIFs in PictureBox anhalten für Hover-Effekt

  • VB.NET

Es gibt 72 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    @RodFromGermany
    Basisklasse ist dann die PictureBox, oder wie? und Overrides überschreibt die Funktion in der Basisklasse dann, sehe ich das richtig?

    RodFromGermany schrieb:

    (private) Namen sind Schall und Rauch

    Was meinst du damit? Meine Frage war so gemeint: Warum der Umweg über einen Konstruktor? Und was genau macht das

    kafffee schrieb:

    AddHandler m_tmr.Tick, AddressOf Timer_Tick


    Und mal noch eine allgemeine Frage: Diese Klasse, kann ich die auch in eine separate Datei auslagern, um sie projektweit zur Verfügung stehen zu haben und ist dies ratsam?

    Sry ich frag dir grad Löcher in den Bauch...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kafffee“ ()

    kafffee schrieb:

    sehe ich das richtig?
    Ja.
    Es gibt in VB.NET zwei Arten, ein Event zu abonieren:

    VB.NET-Quellcode

    1. Private Sub xxx(sender As Object, e As EventArgs) Handles Button1.Click
    2. End Sub
    und

    VB.NET-Quellcode

    1. Public Sub yyy()
    2. AddHandler Button1.Click, AddressOf(xxx)
    3. End Sub
    ====
    Diese Klasse steht doch in einer oder zwei oder drei separaten Dateien (*.vb, *.Designer.vb, *.resx).
    Sie ist überall im Projekt verfügbar, wenn die Klasse den Modifier Public oder Internal hat.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    kafffee schrieb:

    Kann man den Zugriffsmodizierer "Protected" auch weglassen?
    Nein. Protecred bedeutet, dann nur beerbte und vererbte Klassen darauf zugriff haben,
    Wenn keiner da steht, ist eine Prozedur in VBN.NET Public.
    Ein Event abonieren bedeutet, dass Du vom System|Framework benachrichtigt werden willst, wenn ein Event (z.B. Button.Click) eintritt.
    Dazu musst Du einen Eventhandler mit einer entsprechenden Signatur bereitstellen bzw. implementieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich hab das Ganze jetzt mal mit einem anderen GIF ausprobiert. Nur wird dieses schon beim Laden ohne Klick in einer Endlosschleife abgespielt. Wenn ich dann draufklicke gibt es einen Fehler in Zeile 9, Post 57:

    Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt

    mit

    VB.NET-Quellcode

    1. m_bitmap = Nothing
    2. m_CurtrentIndex = 0
    3. m_FrameCount = -1


    Kann das sein dass das einfach nur an der GIF-Datei liegt? Ich hab das mit allen nur erdenklichen Werten für StartIndex und StopIndex probiert, aber es hilft nichts. Und natürlich darauf geachtet, dass das GIF auch entsprechend viele Frames enthält. Ich glaub ich geb jetzt dann auf... ;(

    kafffee schrieb:

    Kann das sein dass das einfach nur an der GIF-Datei liegt?
    Jou.
    Es gibt also (mindestens) 3 (drei) Sorten von GIF-Formaten:
    1. Die, die sich von Deinem Code animieren lassen (Deine ursprüngliche GIF),
    2. die, die sich von Deinem Code nicht animieren lassen (meine Test-GIF),
    3. die, die keinen Animator benötigen.
    Um die Exception zu identifizieren musst Du mal in diesem Zustand über die einzelnen Variablen HOvern, da wird dann bei einer Nothing angezeigt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    OK dann wird mir einiges klar. So macht das Ganze keinen Sinn für mich, ausser ich fang jetzt an die Gifs zu editieren.
    Schade eigentlich. Ich kümmer mich jetzt erstmal um den Rest meines Projekts, vielleicht hab ich später Lust mich da wieder reinzuhängen..
    Trotzdem viel gelernt (v. a. das mit den vererbten Klassen).
    Also danke für die Mitarbeit und ich schließe jetzt das Thema fürs Erste...
    :) :)

    kafffee schrieb:

    ausser ich fang jetzt an die Gifs zu editieren.
    Du brauchst Deinen GIF-Editor, der GIFs macht, die Du darstellen kannst.
    Vorhandene GIFs zerelegen kannst Du mit dem IrfanView.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    RodFromGermany schrieb:

    Vorhandene GIFs zerelegen kannst Du mit dem IrfanView

    Ach komm, das proggen wir doch fix selber. ;)
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Public Class Form1
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. ' GIF laden
    6. Using gif As Bitmap = New Bitmap("D:\Programming\VBC\GDI+\avatar.gif")
    7. ' Anzahl der Frames ermitteln
    8. Dim intFrameCount As Integer = gif.GetFrameCount(Imaging.FrameDimension.Time)
    9. ' mehr als 1 Frame müssen vorhanden sein!
    10. If intFrameCount > 1 Then
    11. ' alle Frames durchlaufen
    12. For intFrameItem As Integer = 0 To intFrameCount - 1
    13. ' Frame selektieren
    14. gif.SelectActiveFrame(Imaging.FrameDimension.Time, intFrameItem)
    15. ' Frame
    16. Using gifFrame As Bitmap = New Bitmap(gif)
    17. ' gifFrame könnte hier zB. als PNG (32bppARGB) gespeichert werden
    18. ' gifFrame.Save("d:\GifFrame" & Convert.ToString(intFrameItem).PadLeft(3, "0"c) & ".png", Imaging.ImageFormat.Png)
    19. ' oder wir konvertieren die 32bppARGB-Bitmap in 24bppRGB Bitmap
    20. Using gifBitmap As Bitmap = New Bitmap(gifFrame.Width, gifFrame.Height,
    21. Imaging.PixelFormat.Format24bppRgb)
    22. Using gra As Graphics = Graphics.FromImage(gifBitmap)
    23. gra.DrawImage(gifFrame, New Point(0, 0))
    24. End Using
    25. ' als 24bppRGB Bitmap speichern
    26. gifBitmap.Save("d:\GifFrame" & Convert.ToString(intFrameItem).PadLeft(3, "0"c) & ".bmp",
    27. Imaging.ImageFormat.Bmp)
    28. End Using
    29. End Using
    30. Next
    31. MessageBox.Show("Fertig", "Gif2Bmp", MessageBoxButtons.OK,
    32. MessageBoxIcon.Information)
    33. Else
    34. ' nur 1 Frame in der GIF
    35. MessageBox.Show("Diese GIF ist keine 'animierte GIF'!", "Gif2Bmp",
    36. MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    37. End If
    38. End Using
    39. End Sub
    40. End Class

    Mfg -Franky-

    RodFromGermany schrieb:

    Du brauchst Deinen GIF-Editor, der GIFs macht, die Du darstellen kannst.
    Vorhandene GIFs zerlegen kannst Du mit dem IrfanView.


    Ist schon alles passiert, hab im Internet Gif-X gefunden, damit geht beides. Bin aber noch nicht dazu gekommen, die Möglichkeiten ausführlich zu testen. Eine Einstellung zum automatisch animieren oder auch nicht hab ich bis jetzt noch nicht gefunden...

    @-Franky-
    Wow das hast du alles von Null aus dem Ärmel geschüttelt? Ich mein verstehen tut man den Code aber das selber zu schreiben in kurzer Zeit...?

    -Franky- schrieb:

    Ach komm, das proggen wir doch fix selber.
    Kann der alle (mindestens) drei Sorten GIF-Formate?
    Bei mir kam bei 18 Bildern ein FrameCount = 1 zurück.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Kann der alle (mindestens) drei Sorten GIF-Formate?

    Also: Mein kleiner Code kann normale, nicht animierte, GIFs (1 Frame) und valide animierte GIFs (mehr als 1 Frame) verarbeiten. Bei nicht validen animierten GIFs, wird halt nur das erste Frame, also so wie bei normalen, nicht animierten, GIFs ausgelesen.

    Ich weis jetzt nicht wie GDI+ intern prüft ob es sich um eine valide animierte GIF handelt. Daher nur geraten. Vermutlich prüft GDI+ im "Application Extension Block" der GIF das Byte 16. Ist dieses 1, dann ist es eine animierte GIF, ist der Wert = 0, dann ist es keine Animierte GIF (egal wie viele Frames in der GIF enthalten sind). Ich kann mit meinem WIC-Code zum erzeugen von animierten GIFs valide und auch nicht valide animierte GIFs durch setzen des entsprechenden Bytes erzeugen. Siehe Bildanhang bei Hex 1C. Die test_ok.gif wird ganz normal abgespielt bzw man kann hier alle Frames extrahieren. Bei test_nok.gif wird nur das erste Frame angezeigt und man kann auch nur das erste Frame, per GDI+, extrahieren.

    Wenn man dennoch alle Frames aus einer nicht validen animierten GIF extrahieren möchte, müsste man die GIF binär einlesen, entsprechende Blöcke auswerten bis man an die eigentlichen Bilddaten kommt. Auf dieser Seite wird das GIF-Format recht gut beschrieben: giflib.sourceforge.net/whatsinagif/bits_and_bytes.html und giflib.sourceforge.net/whatsin…ion_and_transparency.html
    Bilder
    • GifHeader.jpg

      42,32 kB, 1.191×90, 46 mal angesehen
    Mfg -Franky-

    -Franky- schrieb:

    Wenn man dennoch alle Frames aus einer nicht validen animierten GIF extrahieren möchte,
    nimmt man z.B. den IrfanView.
    Sag ich doch. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!