Scrollen einer PictureBox

  • VB.NET

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

    Scrollen einer PictureBox

    Folgendes Problem:

    Ein Bild, welches größer als die PictureBox ist soll mithilfe der ScrollBars gescrollt werden. Die Scrollbars sind bereits da!
    Dieses Problem wurde bereits angesprochen, aber die Lösung, die PictureBox in einem Panel zu verschieben kommt nicht in Frage, weil die Größe der PictureBox und das darin angezeigte Bild mit soziemlich dem ganzen restlichen Programm zusammenhängen.
    Ich würde das so lösen, dass ich aus dem Originalbild den Teil herauszeichne, welcher in die PictureBox passt und diesen Teil dann anzeige.
    Aber wie kann ich diesen Teil möglichst elegant auslesen? Es würde zwar mit Schleifen funktionieren, indem man jedes einzelne Pixel ausliest und anhängt, das wird aber im Nachhinein wenn die Größe der PictureBox verändert wird etwas langsam sein.
    Auch mit den Werten der ScrollBars bin ich mir noch nicht ganz sicher.
    Ich hätte mir das so vorgestellt:

    VB.NET-Quellcode

    1. 'Diese Sub wird nach dem Laden des Bildes aufgerufen
    2. Private Sub SetScrollValues()
    3. 'Wenn das Zoomverhalten der PictureBox auf "Zoom" gestellt ist
    4. 'wäre das Verwenden der Scrollfunktion sinnlos
    5. If PictureBox_Anzeige.SizeMode = PictureBoxSizeMode.Zoom Then
    6. 'Für die Optik werden die Maximum-Werte auf 0 gesetzt
    7. ScrollBar_X.Maximum = 0
    8. ScrollBar_Y.Maximum = 0
    9. Else
    10. 'Weiters muss das Bild in der Picturebox in den X oder Y Werten
    11. 'größer als die der PictureBox selbst sein (sorry, Grammatik)
    12. If PictureBox_Anzeige.Image.Width > PictureBox_Anzeige.Width Then
    13. 'Diese undurchschaubare Rechnung ergibt sich so: Wenn die ScrollBar_X ganz links ist
    14. '(also die "Value" Eigenschaft den Wert null hat) liegt das Pixel 0 des Originalbildes
    15. 'am linken Rand. Wenn die ScrollBar ganz rechts ist und der Maximum Wert gleich dem Wert
    16. 'der "Width" Eigenschaft des Bildes wäre, würde der rechte Rand des Bildes entsprechend
    17. 'der Verschiebung nach links aus dem Rand der PictureBox verschwinden. Darum diese Rechnung
    18. ScrollBar_X.Maximum = PictureBox_Anzeige.Image.Width - PictureBox_Anzeige.Width
    19. 'Anschließend wird (Infolge des Scrollens) zentriert
    20. ScrollBar_X.Value = ScrollBar_X.Maximum / 2
    21. Else
    22. ScrollBar_X.Maximum = 0
    23. End If
    24. If PictureBox_Anzeige.Image.Height > PictureBox_Anzeige.Height Then
    25. 'Das selbe wie vorher
    26. ScrollBar_Y.Maximum = PictureBox_Anzeige.Image.Height - PictureBox_Anzeige.Height
    27. ScrollBar_Y.Value = ScrollBar_Y.Maximum / 2
    28. Else
    29. ScrollBar_Y.Maximum = 0
    30. End If
    31. End If
    32. End Sub
    33. 'Die folgenden Ereignisse bearbeiten nun das Scrollen des Bildes
    34. Private Sub ScrollX() Handles ScrollBar_X.Scroll
    35. End Sub
    36. Private Sub ScrollY() Handles ScrollBar_Y.Scroll
    37. End Sub

    (Das mit den Einzügen funktioniert irgendwie nicht richtig)


    Also in die Events "ScrollX()" und "ScrollY()" würde dann der Code von euch Pro's reinkommen.
    Ja, ich weiß-> kein C&P.

    Ich hab noch einen Screenshot der Form angehängt, die angezeigt wird. Wenns hilft.
    Bilder
    • VB.PNG

      86,15 kB, 1.099×609, 426 mal angesehen
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Epic schrieb:

    [...] Panel adden, picbox rein, Panel autoscroll=true bei picbox bildlayout autosize und fertig.
    Ich hab das mal so probiert. Das mit dem scrollen funktioniert schonmal nicht schlecht. Aber wie bereits erwähnt: Die Größe der PictureBox hängt mit dem restlichen Programm zusammen. Wenn ich das Bild auf die Größe der PictureBox (in dem Fall des Panels) skaliere und die "Sizemode" Eigenschaft wieder auf "Normal" setze wird die PictureBox ganz klein und lässt sich auch durch das Zurückändern der Eigenschaften nicht mehr in die normale Größe bringen.
    Ich könnte mal das Projekt anhängen. Dann wird deutlich, warum das mit dem Panel nicht so gut funktioniert.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Hmm, ja das stimmt. Das Bild müsste dann immer auf AutoSize sein. Wie wärs wenn du dann diese Methode lääst und vielleicht einmal das hier zum Ausschneiden eines Bereiches aus einem Bild hernimmst?

    VB.NET-Quellcode

    1. Public Function GetPicturePart(ByVal SourceImage As Image, ByVal Region As Rectangle) As Bitmap
    2. Dim ImagePart As Bitmap = New Bitmap(Region.Width, Region.Height)
    3. Using G As Graphics = Graphics.FromImage(ImagePart)
    4. Dim TargetRect As Rectangle = New Rectangle(0, 0, Region.Width, Region.Height)
    5. Dim SourceRect As Rectangle = Region
    6. G.DrawImage(SourceImage, TargetRect, SourceRect, GraphicsUnit.Pixel)
    7. End Using
    8. Return ImagePart
    9. End Function


    (Off-Topic): Du fragts in deinem Profil für was die Registerkarte Quellcode steht? Das ist wie beim Themeneditor, du kannst dort nicht mit WYSIWYG arbeiten sondern halt nur mit BB-Codes.
    Vielen Dank für die schnellen Antworten.

    Die Lösung von Epic funktioniert genau so, wie ich es gehofft habe.
    (Und danke für den Hinweis mit der Registerkarte)

    Ich hab's dann so wie beim ersten Mal beschrieben gemacht. Nur die Events für das Scrollen der X und Y ScrollBar lösen das selbe Ereignis aus.

    VB.NET-Quellcode

    1. Private Sub ScrollXY() Handles ScrollBar_X.Scroll, ScrollBar_Y.Scroll
    2. If PictureBox_Anzeige.SizeMode = PictureBoxSizeMode.Normal Then
    3. PictureBox_Anzeige.Image = GetPicturePart(ActualImage100, New Rectangle(New Point(ScrollBar_X.Value, ScrollBar_Y.Value), New Size(PictureBox_Anzeige.Width, PictureBox_Anzeige.Height)))
    4. End If
    5. End Sub
    6. Public Function GetPicturePart(ByVal SourceImage As Image, ByVal Region As Rectangle) As Bitmap
    7. Dim ImagePart As Bitmap = New Bitmap(Region.Width, Region.Height)
    8. Using G As Graphics = Graphics.FromImage(ImagePart)
    9. G.DrawImage(SourceImage, New Rectangle(0, 0, Region.Width, Region.Height), Region, GraphicsUnit.Pixel)
    10. End Using
    11. Return ImagePart
    12. End Function


    Natürlich kann man das Ganze noch verfeinern aber das Ergebnis kann sich sehen lassen.

    Danke :thumbsup:
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils