mit gdi eine linie zeichen die die farbe darunter zu volltranperent ändert

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von Gelöschter Benutzer.

    mit gdi eine linie zeichen die die farbe darunter zu volltranperent ändert

    hallo,

    habe ein problem(wer hätts gedacht :whistling: )

    naja wie auch immer ich habe eine picturebox mit fore und background image und ich möchte auf dem image (also im layersystem das was oben liegt) eine linie zeichen

    das krieg ich auch noch hin nur möchte ist das so machen, dass nicht eine farbige linie gezeichnet wird, sondern dass das bild an dieser stelle transperent wird(also das backgroundimage durchscheint)

    hab schon google und die suchfunktion befragt doch nichts gefunden(vllt benutze ich ja einfach die falschen wörter^^)

    hoffe ihr könnt mir helfen:)

    danke im vorraus
    hmm das wird eher schwer so richtig zu bewältigen...
    meine Idee dazu wäre:
    1. du machst einen GraphicsPath fügst ein Rechteck(größe der PictureBox) hinz und anschließend die Linie(GraphicsPath.AddLine)
    2. diesen GraphicsPath machst du zu einer Region(New Region(...))
    3. du setzt die Region der PictureBox auf eben diese
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    dann machst du es am besten ganz mit GDI+ indem du den Hintergrund sowie das darüberliegende "Kratzbild" im Paint Event zeichnest...

    VB.NET-Quellcode

    1. Private gp As New Drawing2D.GraphicsPath
    2. Private mouseOldPosition As Point
    3. 'MouseDown
    4. mouseOldPosition = e.Location
    5. 'MouseMove
    6. gp.AddLine(mouseOldPosition.X,mouseOldPosition.Y,e.X,e.Y)
    7. mouseOldPosition = e.Location
    8. 'Paint:
    9. e.Graphics.DrawImage(...)'Bild was freigekratzt werden soll
    10. e.Graphics.SetClip(gp)'GraphicsPath
    11. e.Graphics.DrawImage(...)'Bild das weggekratzt wird

    sollte denke ich sogar fast C&P sein^^
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    mhm funkt bei mir so garnicht und wenn ichs so umbaue:

    VB.NET-Quellcode

    1. Private gp As New Drawing2D.GraphicsPath
    2. Private mouseOldPosition As Point
    3. Private Sub Picturebox2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseUp
    4. mouseOldPosition = e.Location
    5. End Sub
    6. Private Sub Picturebox2_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseMove
    7. gp.AddLine(mouseOldPosition.X, mouseOldPosition.Y, e.X, e.Y)
    8. mouseOldPosition = e.Location
    9. Using g As Graphics = PictureBox2.CreateGraphics
    10. g.DrawImage(PictureBox1.Image, New Point(0, 0)) 'Bild was freigekratzt werden soll
    11. g.SetClip(gp) 'GraphicsPath
    12. g.DrawImage(PictureBox1.BackgroundImage, New Point(0, 0)) 'Bild das weggekratzt wird
    13. End Using
    14. End Sub


    spricht das ergebniss für sich selbst :/


    E:
    geht halt immer von der oberen linken ecke aus und wenn man über ne region kommt wo schon 'gekratzt' wurde wird wieder das bild drüber gezeichnet
    hmm liegt wohl daran, dass der Pfad geschlossen wird...
    evtl. funktionierts ja mit FillMode...
    also probier mal beide Varianten aus:

    VB.NET-Quellcode

    1. Private gp As New Drawing2D.GraphicsPath(Drawing2D.FillMode.Winding)

    VB.NET-Quellcode

    1. Private gp As New Drawing2D.GraphicsPath(Drawing2D.FillMode.Alternate)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    bissl umgebaut , geht jetzt nicht mehr von der oberen rechten ecke aber von dem pixel wo man als erstes angesetzt hat und das problem mit dem dass es sich wieder 'zurück kratzt' ist immernoch da :/

    VB.NET-Quellcode

    1. Private gp As New GraphicsPath(Drawing2D.FillMode.Alternate)
    2. Private mouseOldPosition As New Point
    3. Dim kratzen As Boolean = False
    4. Private Sub Picturebox2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseDown
    5. mouseOldPosition = e.Location
    6. kratzen = True
    7. End Sub
    8. Private Sub Picturebox2_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseMove
    9. If kratzen = True Then
    10. gp.AddLine(mouseOldPosition.X, mouseOldPosition.Y, e.X, e.Y)
    11. Using g As Graphics = PictureBox2.CreateGraphics
    12. g.DrawImage(PictureBox1.Image, New Point(0, 0)) 'Bild was freigekratzt werden soll
    13. g.SetClip(gp) 'GraphicsPath
    14. g.DrawImage(PictureBox1.BackgroundImage, New Point(0, 0)) 'Bild das weggekratzt wird
    15. End Using
    16. mouseOldPosition = e.Location
    17. End If
    18. End Sub
    19. Private Sub PictureBox2_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseUp
    20. kratzen = False
    21. End Sub


    E:
    lol das lustige ist wenn ich z.b. in der mitte anfange und dann im uhrzeigersinn drehe stellt sich nichts wiederher , wenn ich dann aber gegen den uhrzeigersinn drehe kommt alles wieder

    E2: hmm wenn ich dann halt in die andere richtung drehe stellt es sich erst wieder her und wird dann wieder weg gekratzt und wenn ich dann wieder andersrum drehe das selbe ..
    habs jetzt so immernoch das selbe problem..

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Drawing.Drawing2D
    3. Imports System.Drawing.Imaging
    4. Public Class Form1
    5. Private gp As New GraphicsPath(Drawing2D.FillMode.Winding)
    6. Private mouseOldPosition As Point
    7. Dim kratzen As Boolean = False
    8. Private Sub Picturebox2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseDown
    9. mouseOldPosition = e.Location
    10. kratzen = True
    11. End Sub
    12. Private Sub Picturebox2_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseMove
    13. If kratzen = True Then
    14. gp.AddLine(New Point(mouseOldPosition.X, mouseOldPosition.Y), New Point(e.X, e.Y))
    15. Using b As Bitmap = New Bitmap(393, 54)
    16. Dim pg As Graphics = Graphics.FromImage(b)
    17. pg.CompositingMode = CompositingMode.SourceCopy ' CompositingMode.SourceOver
    18. Using pg
    19. pg.DrawImage(PictureBox1.Image, 0, 0) 'Bild was freigekratzt werden soll
    20. pg.SetClip(gp) 'GraphicsPath
    21. pg.DrawImage(PictureBox1.BackgroundImage, 0, 0, 393, 54) 'Bild das weggekratzt wird
    22. End Using
    23. PictureBox2.Image = CType(b.Clone, Bitmap)
    24. End Using
    25. Me.Update()
    26. mouseOldPosition = e.Location
    27. End If
    28. End Sub
    29. Private Sub PictureBox2_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseUp
    30. kratzen = False
    31. End Sub
    32. End Class


    und ich setzte jetzt das image der picturebox weils sonst stark flackert
    hmm hätte ja klappen können...

    gut nächste Idee:
    zeichne auf das Kratzbild mit GDI+ deine Linien in einer Farbe, die nirgends auf dem Bild vorkommt(wie wärs mit Pink?!^^), anschließend wendest du noch MakeTransparent auf das Bitmap mit der jeweiligen Farbe an und zeichnest anschließend die beiden Bilder mit GDI+ übereinander, viel Glück ;)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    oder ein Transparentes Bitmap als Brush zeichen ?
    allgemeine Belustigung 8o
    ich weiß nicht was du hast ist doch ganz in Ordnung

    aber ich bin verwirrt: warum rufst du ein eigenes Event auf um zu Zeichnen, warum überschreibst du nicht OnPaint und nutzt ne vernünftige SetStylekombination.
    Weil das im onpaint nur alle paar sekunden erneuert wird und in die performance geht , hiermit ists fluessig und nicht so performance fressend :)

    @jbvsl probier ich mal aus

    @mangafreak
    Da bin ich auch schon drauf gekommen hat aber ned hingehauen :/
    Naja, mit GDI+ fehlt mir teilweise etwas der Durchblick und ich nahm an, das meine Art der Umsetzung doch eher für Heiterkeit sorgt. Das ausradieren mit Transparenz klappte ja noch soweit, blöd war bloß, dass dabei auch jedesmal das Komplette Fenster durchsichtig wurde.

    Ursprünglich war der Plan, ein Label mit dem auszuradierenden Image zu benutzen und dann das BackgroundImage der Form zu sehen. Klappte aber net. Also hab ich einfach mal eine zweite Form hinter der Radier-Form positioniert und dort das Bild angezeigt. Als besonders elegant lässt sich das wohl nicht bezeichnen. ^^

    Wenn ich mir den ganzen Thread mal durchgelesen hätte, würde ich sicherlich auch eine vernünftigere Methode finden, aber dafür hab ich grad keine Zeit . 8-)

    Naja, irgendwann werd ich mir GDI+ wohl mal intensiv vornehmen, wenn ich mal an meinem Spiel weiterkommen will.
    das zeichnen in ein Bitmap und anschließende Darstellen auf der PictureBox ist langsamer, da:
    Die PictureBox im Paint-Event das Bild per GDI+ zeichnet...

    guck dir doch mal SetStyle an, das ist gegen das Flattern...

    die Aktionen mit MakeTransparent usw. setzt du natürlich ins MouseMove Event und nicht ins Paint Event, das dabei entstandene Bitmap speicherst du in einer Variable...

    anschließend zeichnest du im Paint-Event die beiden Bitmaps übereinander, ist performanter :P
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---