Erkennen, ob das gleiche Bild schon in der List(of Bitmap) ist

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von Bartosz.

    Erkennen, ob das gleiche Bild schon in der List(of Bitmap) ist

    Hey,
    ich schreibe eine Prozedur, die aktuell-nicht benötigte Bilder dispost und aktuell benötige einliest. Ich möchte prüfen, ob sich ein Bild bereits in der List(of Bitmap) befindet. Anhand welcher Parameter kann ich das prüfen?

    VB.NET-Quellcode

    1. For j As Integer = 0 To ... Step 1
    2. Using neu_geladenes_Bild As New Bitmap(Pfade_der_Bilder(j))
    3. 'hier prüfen
    4. Bilder.Add(neu_geladenes_Bild)
    5. End Using
    6. Next


    Hinweis: Es kann sein, dass die Liste aktuell leer ist (aber nie nothing ;) ) , es kann sein, dass ein paar Bilder drin sind.
    Und warum merkst/prüfst Du (Dir) nicht einfach die schon verwendeten Bildpfade?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    hier noch ein bissl mehr Code. Ich habe mir eine vergleichende Funktion von Stack******** kopiert. Irre langsam und funzt nicht. Edit: Und falsch melden tut sie auch.

    In meinem Projekt gibt es Threads (sowie hier hahaha) und für jeden Thread gibt es Posts (auch so wie hier hahaha). Pro Post kann es eine verschiedene Anzahl an Bildern geben. So wie ich unten eines anhänge. Das heißt, jede Instanz der Klasse Post hat eine List(of String) mit den Dateipfaden und eine List(of Bitmap) mit den Bildern. Werden diese Bilder aktuell nicht benötigt, werden sie dispost. Wenn sie wieder benötigt werden, werden sie neu eingelesen. Die Liste mit den Dateipfaden gibt es ja noch. Mein Ansatz war jetzt, eine Function zu nutzen, die alle Bilder, die zu einem Post gehören mit dem aktuell geladenen vergleicht. Wenn alle Bilder nicht dem neugeladenen entsprechen, dann hinzufügen. Sofern Bilder vorhanden sind.
    Leider knallt es immer wieder (siehe Anhang). Wahrscheinlich, weil die Bilder dispost worden waren? (was aber auch nicht sein kann, weil ich prüfe ja auf Nothing....) Komisch.


    VB.NET-Quellcode

    1. Private Sub Load_the_pictures_only_when_shown_and_free_up_memory_after_an_Image_is_not_needed()
    2. For g As Integer = 0 To Liste_mit_allen_Threads.Count - 1 Step 1
    3. If g <> SI Then 'Diese Bilder verwerfen
    4. For i As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread.Count - 1 Step 1
    5. For j As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.Count - 1 Step 1
    6. Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder(j).Dispose()
    7. Next
    8. Next
    9. Else 'Diese Bilder laden
    10. For i As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread.Count - 1 Step 1
    11. For j As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.Count - 1 Step 1
    12. Dim BoolArray() As Boolean = New Boolean(Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.Count - 1) {}
    13. Using neu_geladenes_Bild As New Bitmap(Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Pfade_der_Bilder(j))
    14. For k As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.Count - 1 Step 1
    15. If Not Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder(k) Is Nothing Then
    16. BoolArray(k) = Are_Images_equal(Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder(k), neu_geladenes_Bild)
    17. End If
    18. '
    19. Next
    20. For h As Integer = 0 To BoolArray.Length - 1 Step 1
    21. If BoolArray(h) = True Then
    22. Exit For
    23. End If
    24. Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.Add(neu_geladenes_Bild)
    25. Next
    26. End Using
    27. Next
    28. Next
    29. End If
    30. Next
    31. End Sub
    32. Private Shared Function Are_Images_equal(ByVal bmp1 As Bitmap, ByVal bmp2 As Bitmap) As Boolean
    33. If Not bmp1.Size.Equals(bmp2.Size) Then
    34. Return False
    35. End If
    36. For x As Integer = 0 To bmp1.Width - 1
    37. For y As Integer = 0 To bmp1.Height - 1
    38. If bmp1.GetPixel(x, y) <> bmp2.GetPixel(x, y) Then
    39. Return False
    40. End If
    41. Next
    42. Next
    43. Return True
    44. End Function


    @VaporiZed Ich habe zwischenzeitlich geantwortet
    Bilder
    • Screenshot 2021-05-06 161501.png

      157,41 kB, 1.493×873, 59 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Bartosz“ ()

    @Bartosz Nimm statt einer List(Of Bitmap) ein Dictionary(Of String, Bitmap) und lege den Pfad mit ab.
    Anhand des Pfades kannst Du testen, ob die Bitmap schon da ist.
    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!
    Du Disposest deine Bilder direkt, nachdem du sie in die Liste gepackt hast. Deswegen kommt auch deine Fehlermeldung. Mach den Using-Block weg und dispose die Bilder beim FormClosing oä.
    Form_Closing ist zu spät. Ich muss zwischendrin aufräumen.

    Edit: Ich habe es nun provisorisch gelöst. @RodFromGermany Dictionaries muss ich mir noch anschauen :) Ich habe in die Class_Post ein Boolean-Array eingebaut, welches so viele Member hat, wie es in dem Post Bilder und Pfade gibt.
    • Beim Disposen der Bilder eines Posts wird das jeweilige Arraymitglied auf False gesetzt.
    • Beim Wieder-Reinladen der Bilder eines Posts wird das jeweilige Arraymitglied auf True gesetzt.
    • Das Disposen allein reicht nicht, denn der Platz in der Liste bleibt lustigerweise belegt. Man muss zusätzlich mit RemoveAt das Bild komplett löschen, aber in einer rückwärtslaufenden For-Schleife, weil während des Löschens ja die Liste kleiner wird. ;)
    • @'nafets' hatte Recht mit dem Teil, dass kein Using verwendet werden darf. Danke an der Stelle.

    VB.NET-Quellcode

    1. Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
    2. If ComboBox1.SelectedIndex <> (-1) Then
    3. SI = ComboBox1.SelectedIndex
    4. If Programm_fertig_geladen Then
    5. Load_the_pictures_only_when_shown_and_free_up_memory_after_an_Image_is_not_needed()
    6. End If
    7. alle_Posts_in_diesem_Thread_anzeigen()
    8. End If
    9. End Sub
    10. Private Sub Load_the_pictures_only_when_shown_and_free_up_memory_after_an_Image_is_not_needed()
    11. For g As Integer = 0 To Liste_mit_allen_Threads.Count - 1 Step 1
    12. If g <> SI Then 'Diese Bilder verwerfen
    13. For i As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread.Count - 1 Step 1
    14. For j As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.Count - 1 Step 1
    15. Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder(j).Dispose()
    16. Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).BoolArray(j) = False
    17. Next
    18. Dim CNT As Integer = Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.Count
    19. For z As Integer = (CNT - 1) To 0 Step -1
    20. Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.RemoveAt(z)
    21. Next
    22. Next
    23. Else 'Diese Bilder laden
    24. 'für jeden Post
    25. For i As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread.Count - 1 Step 1
    26. 'die Bilder in dem Post
    27. For j As Integer = 0 To Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Pfade_der_Bilder.Count - 1 Step 1
    28. Dim neu_geladenes_Bild As New Bitmap(Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Pfade_der_Bilder(j))
    29. If Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).BoolArray(j) = False Then
    30. Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).Bilder.Add(neu_geladenes_Bild)
    31. Liste_mit_allen_Threads(g).Posts_in_diesem_Thread(i).BoolArray(j) = True
    32. End If
    33. 'End Using
    34. Next
    35. Next
    36. End If
    37. Next
    38. End Sub


    So, dann brauchen wir keine Funktion mehr aus dem Internet kopieren, die 5*2 Bilder à 10 Megapixel vergleicht und 2 Minuten braucht und dann auch noch falschmeldet. :rolleyes:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Bartosz“ ()