Passenstes Icon aus Array extrahieren - Ansatz gesucht

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von FormFollowsFunction.

    Passenstes Icon aus Array extrahieren - Ansatz gesucht

    Hallöchen

    Ich möchte aus einem Array mit Icons, das passenste extrahieren.
    In dem Array können sich Icons mit unterschiedlichen Eigenschaften (Größe, Quallität) befinden.
    Nun möchte ich das passenste (z.B. 32x32 Pixel, 32bit Quallität) erhalten, wenn nicht vorhanden, dann das nächst passende (z.B. 24x24, 32bit Quallität) u.s.w..

    Mir fällt da nur eine recht aufwändige Lösung ein, nähmlich das Array komplett zu durchlaufen und die Icons an Listen (32bit, 24bit u.s.w.) zu übergeben, die dann alle Icons mit gleicher Quallität enthalten.
    Darauf hin erst die Liste mit höchster Qualität zu durlaufen und die passende Größe ausgeben, oder wenn die Liste leer ist, die nächste Liste abhandeln.

    Meine Frage lautet also: Hat jemand eine Idee zu einem anderem, eleganterem Ansatz (LINQ ?) ?
    jo, dass klingt sehr nach linq - group by.
    Allerdings deine Anforderung ist mir noch nicht klar. Ich meine - was die Icons anzeigen ist egal?
    Und wie sind die preferenzen: lieber gross, auch wenn schlecht oder lieber gut, auch wenn klein?

    vielleicht schreibste auch eine kleine Bewertungs-Funktion für Icons, und suchst dann einfach mit MaxBy das Icon mit der höchsten Bewertung:
    verbesserte AggregatFunktion für Linq-Max / Linq-Min

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

    Was die Icons anzeigen ist egal, nur Quallität und Größe sind relevant.
    Hohe Quallität ist primär, Größe ist sekundär, aber in der vollgenden Reihenfolge:

    VB.NET-Quellcode

    1. icon.Size = New Size(32,32)
    2. icon.Width = 32 OrElse icon.Height = 32
    3. icon.Size = New Size(64,64)
    4. icon.Width = 64 OrElse icon.Height = 64
    5. ...
    6. ...
    7. icon.Size = New Size(512,512)
    8. icon.Width = 512 OrElse icon.Height = 512
    9. icon.Size = New Size(24,24)
    10. icon.Width = 24 OrElse icon.Height = 24
    11. ...
    12. ...
    13. icon.Size = New Size(16,16)
    14. icon.Width = 16 OrElse icon.Height = 16


    Mal Size und mal Width und Height abfragem macht es sogar noch scchwieriger, fällt mir dabe auf. ?(
    @FormFollowsFunction Wozu brauchst Du das Icon?
    Wenn Du das einer .Icon-Property zuweisen willst, kannst Du das multiple Icon nehmen, das System sucht sich das passende aus.
    ====
    Was soll das bedeuten:

    FormFollowsFunction schrieb:

    VB.NET-Quellcode

    1. icon.Width = 32 OrElse icon.Height = 32



    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 lese mit einer Library die unterschiedlichen Quallitäten und Größen eines Icons aus, und davon brauche ich eben das passenste, also am besten in 32bit Qualltät und 32x32 Pixel Groß, da es nur in 32x32 Pixel angezeigt wird.
    Wenn nicht vorhanden, dann eben das nächt größere mit mindestens einer Seite 32 Pixel groß, das kann dann eben z.B 32x48 Pixel haben.
    Wenn das nicht vorhanden ist, dann das nächst größere z.B 48x48 Pixel .... et cetera.

    Ich habe jetzt erstmal was simples gebastellt, so bekomme ich schonmal das größte in bestmöglicher Quallität.
    Wenn es zu groß ist sieht es nicht so dolle aus, aber damit kann ertmal ich leben.

    VB.NET-Quellcode

    1. Private Function GetFittestIcon(ByVal _icons As Icon()) As Icon
    2. Dim list32Bit, list24Bit, list8Bit, list4Bit, list1Bit As New Dictionary(Of Integer, Icon)
    3. For Each icon As Icon In _icons
    4. Dim bitCount As Integer = GetBitCount(icon)
    5. Select Case bitCount
    6. Case 32
    7. list32Bit.Add(icon.Width * icon.Height, icon)
    8. Case 24
    9. list24Bit.Add(icon.Width * icon.Height, icon)
    10. Case 8
    11. list8Bit.Add(icon.Width * icon.Height, icon)
    12. Case 4
    13. list4Bit.Add(icon.Width * icon.Height, icon)
    14. Case 1
    15. list1Bit.Add(icon.Width * icon.Height, icon)
    16. End Select
    17. Next
    18. If list32Bit.Count > 0 Then
    19. Return list32Bit.Item(list32Bit.Keys.Max)
    20. ElseIf list24Bit.Count > 0 Then
    21. Return list24Bit.Item(list24Bit.Keys.Max)
    22. ElseIf list8Bit.Count > 0 Then
    23. Return list8Bit.Item(list8Bit.Keys.Max)
    24. ElseIf list4Bit.Count > 0 Then
    25. Return list4Bit.Item(list4Bit.Keys.Max)
    26. ElseIf list1Bit.Count > 0 Then
    27. Return list1Bit.Item(list1Bit.Keys.Max)
    28. End If
    29. Return _icons(0)
    30. End Function
    probierma so:

    VB.NET-Quellcode

    1. Private Function GetFittestIcon(ByVal _icons As Icon()) As Icon
    2. Dim grps = _icons.GroupBy(Function(ic) GetBitCount(ic))
    3. Dim maxGrp = grps.MaxBy(Function(g) g.Key)
    4. Dim maxIcon = maxGrp.MaxBy(Function(ic) ic.Width)
    5. Return maxIcon
    6. End Function
    ach - du hast ja keine MayBy-Extension - bin aber jetzt zu faul.
    @FormFollowsFunction

    RodFromGermany schrieb:

    Was soll das bedeuten:

    FormFollowsFunction schrieb:

    VB.NET-Quellcode

    1. icon.Width = 32 OrElse icon.Height = 32
    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
    Wie FFF gesagt hat, wenn die Weite nicht stimmt muss die Höhe her.
    Hauptsache eines der Größenattribute trifft zu und wenn nicht, dann geht's weiter in der Kiste.

    @FormFollowsFunction
    Ich glaube ich verstehe was du brauchst.
    Was ich tun würde wäre deine Bilddaten in ein Array abzulegen und sortiere sie bei Größe während du die Elemente einfügst, von klein zu groß.
    Dies hat unter anderem den Vorteil das du niemals öfter als einmal das Array dursuchen müssen wirst, da alle Größen aufeinander folgen. (mit ihren Farbtiefen)

    Dann kannst du diese hässlichen switch-statements oder auch anders umständliche If-Netzwerke vermeiden und direkt aus einer Schleife aus entscheiden welches Ergebnis dir geliefert werden sollte.
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------

    Elanda schrieb:

    Wie FFF gesagt hat,
    ist das kein VB-Code, sondern what ever.
    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
    Das dachte ich mir schon fast, aber ich denke es war sowieso zu illustrativen Zwecken gedacht.

    Ein Gedankenspiel umgesetzt in eine allgemein Verstandene Sprache.
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------

    Elanda schrieb:

    in eine allgemein Verstandene Sprache
    Das nennen wir Pseudo-Code. ;)
    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!

    ErfinderDesRades schrieb:

    vielleicht schreibste auch eine kleine Bewertungs-Funktion für Icons, und suchst dann einfach mit MaxBy das Icon mit der höchsten Bewertung:
    verbesserte AggregatFunktion für Linq-Max / Linq-Min

    "... kleine Bewertungs-Funktion ..." Konnte ich mir erst nichts drunter vorstellen, bzw. hat mich etwas abgeschreckt.
    Jetzt habe es aber kapiert.
    Es ist extrem einfach und es funktioniert. :)

    So siehts jetzt aus (An der Bewertungsfunktion werde ich vielleicht noch etwas feilen) :

    VB.NET-Quellcode

    1. <Author("ErfinderDesRades", "https://www.vb-paradise.de/index.php/User/11507-ErfinderDesRadesErfinderDesRades/")>
    2. <EditedBy("FormFollowsFunction", "https://www.vb-paradise.de/index.php/User/26014-FormFollowsFunction/")>
    3. Private Function GetFittestIcon(ByVal _icons As Icon()) As Icon
    4. Dim groups As IEnumerable(Of IGrouping(Of Integer, Icon)) = _icons.GroupBy(Function(icon) GetBitCount(icon))
    5. Dim maxGroup As IGrouping(Of Integer, Icon) = groups.MaxBy(Function(group) group.Key)
    6. Dim maxIcon As Icon = maxGroup.MaxBy(Function(icon) RateIcon(icon))
    7. Return maxIcon
    8. End Function
    9. Private Function RateIcon(ByVal _icon As Icon) As Integer
    10. If _icon.Width < 32 OrElse _icon.Height < 32 Then Return -10000
    11. Dim rate As Integer
    12. rate -= _icon.Width
    13. rate -= _icon.Height
    14. Return rate
    15. End Function


    Die Extensions habe ich noch etwas an meinen Programmierstil angepasst und
    werde versuchen die Funktionweise vollständig nachzuvollziehen :
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.CompilerServices
    2. <Author("ErfinderDesRades", "https://www.vb-paradise.de/index.php/User/11507-ErfinderDesRadesErfinderDesRades/")>
    3. <EditedBy("FormFollowsFunction", "https://www.vb-paradise.de/index.php/User/26014-FormFollowsFunction/")>
    4. <Version("1.0.0.1")>
    5. <Source("https://www.vb-paradise.de/index.php/Thread/85067-verbesserte-AggregatFunktion-f%C3%BCr-Linq-Max-Linq-Min/?postID=699077&highlight=maxby#post699077")>
    6. Module BetterAggregatExtensions
    7. ''' <summary>
    8. ''' Gibt die Structure 'MinMax', die den Minimalwert und den Maximalwert aus einer generischen Sequenz enthält, zurück.
    9. ''' </summary>
    10. <Extension()>
    11. Public Function Extremum(Of T, T2 As IComparable)(
    12. ByVal items As IEnumerable(Of T), ByVal selector As Func(Of T, T2)) As MinMax(Of T, T2)
    13. With items.GetEnumerator
    14. If Not .MoveNext Then .Dispose() : Return Nothing
    15. Extremum = New MinMax(Of T, T2)(.Current, selector)
    16. While .MoveNext : Extremum.Check(.Current) : End While
    17. .Dispose()
    18. End With
    19. End Function
    20. ''' <summary>
    21. ''' Gibt den Träger des Maximalwertes in einer generischen Sequenz zurück.
    22. ''' </summary>
    23. <Extension()>
    24. Public Function MaxBy(Of T, T2 As IComparable)(
    25. ByVal items As IEnumerable(Of T), ByVal selector As Func(Of T, T2)) As T
    26. Return items.Extremum(selector).Maximum
    27. End Function
    28. ''' <summary>
    29. ''' Gibt den Träger des Minimalwertes in einer generischen Sequenz zurück.
    30. ''' </summary>
    31. <Extension()>
    32. Public Function MinBy(Of T, T2 As IComparable)(
    33. ByVal items As IEnumerable(Of T), ByVal selector As Func(Of T, T2)) As T
    34. Return items.Extremum(selector).Minimum
    35. End Function
    36. Public Structure MinMax(Of T, T2 As IComparable)
    37. Public Minimum, Maximum As T
    38. Public MinValue, MaxValue As T2
    39. Private ReadOnly Selector As Func(Of T, T2)
    40. Public ReadOnly HasValue As Boolean
    41. Public Sub New(ByVal _first As T, ByVal _selector As Func(Of T, T2))
    42. Selector = _selector
    43. Minimum = _first : Maximum = _first
    44. MinValue = Selector(_first) : MaxValue = MinValue
    45. HasValue = True
    46. End Sub
    47. Public Sub Check(ByVal _item As T)
    48. Dim value As T2 = Selector(_item)
    49. If value.CompareTo(MinValue) < 0 Then
    50. Minimum = _item
    51. MinValue = value
    52. ElseIf value.CompareTo(MaxValue) > 0 Then
    53. Maximum = _item
    54. MaxValue = value
    55. End If
    56. End Sub
    57. End Structure
    58. End Module
    59. #Region "Attribute Classes"
    60. Friend Class AuthorAttribute
    61. Inherits Attribute
    62. Public Property Name As String
    63. Public Property ContactAddress As String
    64. Sub New(ByVal _name As String)
    65. Name = _name
    66. End Sub
    67. Sub New(ByVal _name As String, ByVal _contactAddress As String)
    68. Name = _name
    69. ContactAddress = _contactAddress
    70. End Sub
    71. End Class
    72. Friend Class EditedByAttribute
    73. Inherits Attribute
    74. Public Property Name As String
    75. Public Property ContactAddress As String
    76. Sub New(ByVal _name As String)
    77. Name = _name
    78. End Sub
    79. Sub New(ByVal _name As String, ByVal _contactAddress As String)
    80. Name = _name
    81. ContactAddress = _contactAddress
    82. End Sub
    83. End Class
    84. Friend Class VersionAttribute
    85. Inherits Attribute
    86. Public Property Version As String
    87. Sub New(ByVal _version As String)
    88. Version = _version
    89. End Sub
    90. End Class
    91. Friend Class SourceAttribute
    92. Inherits Attribute
    93. Public Property Source As String
    94. Sub New(ByVal _source As String)
    95. Source = _source
    96. End Sub
    97. End Class
    98. #End Region


    Danke an alle, besonders an EDR ! :thumbsup:

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