How to zoom in a Picturebox with scrollwheel in vb.net

后端 未结 3 1898
挽巷
挽巷 2020-12-16 03:19

I\'m using a set of graphics overlays to draw an image inside a picturebox control using the graphics object. I have placed the Picturebox inside a Panel and set the Panel t

相关标签:
3条回答
  • 2020-12-16 03:57

    basically, you need an image viewer. I used this before: http://cyotek.com/blog/creating-a-scrollable-and-zoomable-image-viewer-in-csharp-part-4

    it works great. however, it is an user control.

    for picturebox, you need create graphics from the image, and then interpolation it. here is an example: http://www.dotnetcurry.com/ShowArticle.aspx?ID=196

    I did not check this one, but looks like will work.

    0 讨论(0)
  • 2020-12-16 04:03

    I noticed that there's an undesirable effect with the StretchImage SizeMode that ignores the image ratio. I just added a width and height ratio variable to include in the "zoom" algorithm. See _ratWidth and _ratHeight in code below.

    Public Class Form1
    
    Private _originalSize As Size = Nothing
    Private _scale As Single = 1
    Private _scaleDelta As Single = 0.0005
    Private _ratWidth, _ratHeight As Double
    
    Private Sub Form_MouseWheel(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
    
        'if very sensitive mouse, change 0.00005 to something even smaller   
        _scaleDelta = Math.Sqrt(PictureBox1.Width * PictureBox1.Height) * 0.00005
    
        If e.Delta < 0 Then
            _scale -= _scaleDelta
        ElseIf e.Delta > 0 Then
            _scale += _scaleDelta
        End If
    
        If e.Delta <> 0 Then _
        PictureBox1.Size = New Size(CInt(Math.Round((_originalSize.Width * _ratWidth) * _scale)), _
                                    CInt(Math.Round((_originalSize.Height * _ratHeight) * _scale)))
    
    End Sub
    
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
    
        'init this from here or a method depending on your needs
        If PictureBox1.Image IsNot Nothing Then
            _ratWidth = PictureBox1.Image.Width / PictureBox1.Image.Height
            _ratHeight = PirctureBox1.Image.Height / PictureBox1.Image.Width
            PictureBox1.Size = Panel1.Size
            _originalSize = Panel1.Size
        End If
    End Sub
    End Class
    
    0 讨论(0)
  • 2020-12-16 04:06

    You can try this code. It assumes there exist a Panel1 and PictureBox1 on the form (PictureBox1 inside the Panel1 with Panel1.AutoScroll = True) with an image set on the PictureBox.

    The code doesn't calculate center point of the zoom, but you can use the e.Location (or e.X/e.Y) for that.

    Update - here is the new code that is (should be) more robust than the previous (see bottom):

    Public Class Form1
    
        Private _originalSize As Size = Nothing
        Private _scale As Single = 1
        Private _scaleDelta As Single = 0.0005
    
        Private Sub Form_MouseWheel(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
    
            'if very sensitive mouse, change 0.00005 to something even smaller   
            _scaleDelta = Math.Sqrt(PictureBox1.Width * PictureBox1.Height) * 0.00005
    
            If e.Delta < 0 Then
                _scale -= _scaleDelta
            ElseIf e.Delta > 0 Then
                _scale += _scaleDelta
            End If
    
            If e.Delta <> 0 Then _
            PictureBox1.Size = New Size(CInt(Math.Round(_originalSize.Width * _scale)), _
                                        CInt(Math.Round(_originalSize.Height * _scale)))
    
        End Sub
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
    
            'init this from here or a method depending on your needs
            If PictureBox1.Image IsNot Nothing Then
                PictureBox1.Size = Panel1.Size
                _originalSize = Panel1.Size
            End If
    
        End Sub
    
    End Class
    

    Old code - works, but is unstable on large changes probably due to rounding errors in Scale():

    Public Class Form1
    
        Private _scale As New SizeF(1, 1)
        Private _scaleDelta As New SizeF(0.01, 0.01) '1% for each wheel tick
    
        Private Sub Form_MouseWheel(sender As System.Object, 
                                    e As MouseEventArgs) Handles Me.MouseWheel
    'count incrementally 
            _scale.Height = 1
            _scale.Width = 1
    
            If e.Delta < 0 Then
                _scale += _scaleDelta
            ElseIf e.Delta > 0 Then
                _scale -= _scaleDelta
            End If
    
            If e.Delta <> 0 Then _
            PictureBox1.Scale(_scale)
    
        End Sub
    
        Private Sub Form1_Load(sender As System.Object, 
                               e As EventArgs) Handles MyBase.Load
    
            PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
    
            'init picturebox size = image size
            If PictureBox1.Image IsNot Nothing Then
                PictureBox1.Scale(New SizeF(1, 1))
                PictureBox1.Size = PictureBox1.Image.Size
            End If
    
        End Sub
    
    End Class
    
    0 讨论(0)
提交回复
热议问题