Bekanntes "Überlappen zweier Transparenter Bilder" Problem

  • VB.NET

Es gibt 55 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    Bekanntes "Überlappen zweier Transparenter Bilder" Problem

    Moin,

    War ja länger nicht da und mit der SuFu habe ich auch nichts gefunden.
    Deshalb wollte ich nochmal nachfragen gibt es für das Problem eig. schon eine Lösung?

    Also wenn man mehrere Transparente Bilder zeichnet und die sich irgentwann überlappen
    scheint an den Transparenten stellen ja der Background durch und nicht das darunter liegende Bild..

    Gibts da schon eine neue Methode?
    Bilder
    • Beispiel.png

      13,17 kB, 561×209, 120 mal angesehen
    Wenn ich die Bilder mit GDI Zeiche (in eine Picturebox oder in eine Form) habe ich am ende den Selben Effect sobald diese sich überlagern.

    Edit: Kann auch sein das ich GDi falsch anwende.. falls du sir sicher bist das geht kannst du mir villeicht genau sagen wie bzw. wo du drauf zeichnest?

    Edit2: Wäre als alternative (wenn GDI+ nciht klappt) XNA eine Lösung? Tritt der Fehler bei einem 2D SpriteBatch auch auf?
    GDI+ klappt hier sehr wohl, jedoch musst du es(ebenso wie in XNA) alles auf eine Fläche und somit ein Control zeichnen, dort hast du dann die Möglichkeit alle arten von Transparenz anzuwenden, zwischen verschiedenen Controls geht dies nicht, bzw. nicht so einfach...(WPF wäre dort dann wohl eher angebracht...)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Ok also alles auf eine Bitmap..
    Werde es versuchen.

    Mir fällt grade ein das ich jetzt versuchen wollte ca. 30 Bilder in ein Bild zu zeichen..
    Es wird bestimmt sehr sehr unübersichtlich falls mir eine Methode einfällt die Positionen und so zu Handeln..
    Oha

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

    nein doch nicht auf ein Bitmap, sondern auf ein Control im Paint Event...
    um das ganze schön zu strukturieren kannst du dir ja eine Klasse schreiben, ca. so:

    VB.NET-Quellcode

    1. Public Class Bild
    2. Property Bitmap...
    3. Property Position...
    4. Sub Draw(g As Graphics)
    5. g.DrawImage(Bitmap,Position)
    6. End Sub
    7. End Class

    nur noch entsprechend für deine Verhältnisse anpassen(die Bilder kannst du somit auch in ein Array schreiben, wodurch du das ganze nachher dynamisch in einer Schleife anzeigen lassen kannst...)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    jvbsl schrieb:


    VB.NET-Quellcode

    1. Property Bitmap...




    VB.NET-Quellcode

    1. Public Class Zeichnen
    2. '###############################################
    3. Dim FILENAMME As String
    4. Dim HÖHE As Integer
    5. Dim G As Graphics = Renderform.CreateGraphics
    6. Dim Bitmap As New Bitmap(FILENAMME, HÖHE, G)
    7. Dim Position As Point
    8. Dim Pfad As String
    9. '###############################################
    10. Property PPfad As String
    11. Get
    12. Return Pfad
    13. End Get
    14. Private Set(ByVal Wert As String)
    15. Pfad = Wert
    16. End Set
    17. End Property
    18. Property PPosition As Point
    19. Get
    20. Return Position
    21. End Get
    22. Private Set(ByVal Wert As Point)
    23. Position = Wert
    24. End Set
    25. End Property
    26. Private Sub Rendern()
    27. G.DrawImage(Bitmap, Position)
    28. End Sub
    29. End Class


    Also so sieht meine Klasse bis jetzt auch sie ist noch nicht ganz Fertig und auch noch nicht ganz durchdacht.. :S aber ich bin dank dir schonmal auf den richtigen weg..
    Was ich mich jetzt noch frage ist was sollte "Property Bitmap..." werden? Wenn ich jetzt alle zu zeichnende Bilder in ein Array lade und mit einer For each Schleife durchgehe bekommt jedes Bild sein Pfad seine Position und wird gezeichnet "G.DrawImage(Bitmap, Position)" und wenn ich am ende der Schleife Renderform.Invalidate aufrufe wird alles auf die Form gezeichnet.. ist das so richtig? Habe ich dann damit das Problem umschifft?

    Gruß Eistee
    Das tuhe ich ja

    VB.NET-Quellcode

    1. Dim G As Graphics = Renderform.CreateGraphics
    Ich zeichne damit direkt auf die Form "Renderform"

    Was ich wissen muss ist das richtig das mit dieser Methode
    das problem gelöst ist..

    Werden die Bilder hiermit:

    VB.NET-Quellcode

    1. G.DrawImage(Bitmap, Position)
    alle "in den Speicher geladen" und erst beim aufruf von

    VB.NET-Quellcode

    1. Renderform.Invalidate
    auf die Form gemalt so das dieses Überlappen nicht mehr auftritt?
    Die Property brauchst du damit du auch was zeichnest ^^. Wenn du ein Bitmap zeichnen willst, dann brauchst du auch eine Bitmap-Variable. Und damit das dynamisch ist und du nicht immer von der Datei, das laden musst nehmen wir ne Property
    Also:

    VB.NET-Quellcode

    1. Property PBitmap As Bitmap
    2. Get
    3. Return Bitmap
    4. End Get
    5. Private Set(ByVal Wert As String)
    6. Bitmap = New Bitmap(Wert, HÖHE, G)
    7. End Set
    8. End Property


    Damit würde Pfad dann ja wegfallen?
    Aber irgentwie kann das ja nicht gehen da der Parameter kein String sein darf sondern eine Bitmap sein müsste..
    Ich glaube ich verstehe das grade falsch. :rolleyes:



    Edit: Ahhh oder ehr doch so:

    VB.NET-Quellcode

    1. Property PBitmap As Bitmap
    2. Get
    3. Return Bitmap
    4. End Get
    5. Private Set(ByVal Wert As Bitmap)
    6. Bitmap = New Bitmap(Pfad, HÖHE, G)
    7. End Set
    8. End Property


    Was mir grade so auffällt komisch das mann eine Höhe definieren soll aber breite ist egal.. ^^
    CreateGraphics = Böse(zumindest in den meisten fällen^^)
    mach einen Übergabeparameter für die Rendern Methode vom Type graphics, im Paint Event übergibst du dann e.Graphics...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    wieso deklarieren ? und g ist in diesem Fall die Graphics von Renderform

    warum umständlich ?

    VB.NET-Quellcode

    1. Public [Bitmap] As Bitmap
    wird zwar kein Event ausgelöst, aber das brauchst du ja nicht. du weißt ja wann es gewechselt wird :)
    die [ ] um Bitmap sind um den Namen Bitmap verwendbar zu machen, da Bitmap ja schon eine Klasse ist und somit ein reservierter Name
    du sollst das so machen :
    Klasse von jvbsl

    VB.NET-Quellcode

    1. Public Class TBitmap
    2. Public [Bitmap] As Image ' das Bild
    3. Public Position As Point ' wo das Bild später hin soll man könnte auch ein Rectangle nehmen ... zum Zeigen reicht ein Point aus
    4. Public Sub New(Optional ByVal bmp As Image = Nothing, Optional ByVal pt As Point = Point.Empty)
    5. ' beim Initialisieren schon mal Werte zuweisen
    6. Me.[Bitmap] = bmp
    7. Me.Position = pt
    8. End Sub
    9. Public Sub Render(ByVal g As Graphics)
    10. If [Bitmap] IsNot Nothing Then g.DrawImage([Bitmap], Position) ' wenn das Bild auch was ist (also nicht Nichts) wirds auch gezeichnet
    11. End Sub
    12. End Class

    So verwenden
    Public Class Form1
    Public bmps() As TBitmap = New TBitmap() {New TBitmap(Image.FromFile("irgendeinPfad/bild1.***").Clone(), New Point(10, 10)), New TBitmap(Image.FromFile("irgendeinPfad/bild2.***").Clone(), New Point(100, 100))}
    Private Sub Form1_Draw(ByVal sender As Object, ByVal e As GraphicsEvent?) Handles Form1.Draw
    For Each bmp As TBitmap In bmps
    bmp.Render(e.Graphics)
    Next
    End Sub
    End Class

    ich denke mal, dass er es so meinte
    Danke nochmal für eure bisherige Hilfe!




    Das mit den einzelnen Bildern klappt jetzt ja ganz gut, nur jetzt fällt mir gerade ein,
    das ich keine Bilder zeichnen will, sondern das jedes einzelne "Bild" was am ende
    auf das Control gezeichnet wird in Wirklichkeit alles Animationen sind. :cursing:

    Bekomme gerade voll den Anfall deswegen..
    Dachte mir, ich mach für jede Animation eine eigene Liste, wo dann beim neuzeichnen (Control Invalidate)
    jedesmal ein anderes Bild gezeichnet wird, bis da durch dann die Animation entsteht.

    Blöd ist dann nur das die Animation Geschwindigkeit von der Refresh-rate abhängig ist, was in einigen
    fällen blöd aussehen würde da machen Animation einfach schneller sein müssen als andere.

    Habt ihr da vielleicht eine bessere Idee wie ich das Problem lösen könnte?

    Muss jetzt erstmal zum Apotheke mir was gegen die Krätze besorgen die ich dadurch bekommen habe.
    Gruß Eistee
    Ich habe da im Kopf so eine AnimatedSprite-Klasse aus dem XNA-Bereich. Damit kannst du zwar keine Animationen aus gifs importieren, aber selbst welche machen.
    Gefunden habe ich sie hier. Du müsstest sie nur noch übersetzen bzw. aus XNA nach WinForm übersetzen. Wenn du willst kann ich das auch tun. (aber jetzt nicht mehr ^^).
    So war das im Endeffekt meine Umsetzung. Ich denke für Animationen ist die Klasse gut geeignet.