简体   繁体   English

如何在vb.net中使用滚轮放大Picturebox

[英]How to zoom in a Picturebox with scrollwheel in vb.net

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 to autoscroll. 我已将Picturebox放在Panel中,并将Panel设置为自动滚动。 What I need to know how to do now is use the Mouse scroll wheel to blow up the size of the picture in small increments while maintaining the quality of the image drawn. 我现在需要知道的是使用鼠标滚轮以小幅度增大图片的大小,同时保持绘制图像的质量。 Anyone know how to do this? 有人知道怎么做吗?

When I update with Abdias Software code below, the picture starts out smaller when Sizemode property of picturebox is set to StretchImage. 当我使用下面的Abdias软件代码更新时,当picturebox的Sizemode属性设置为StretchImage时,图片开始变小。 I have a pan feature with the mouse that might be interfering with keeping this code from working properly. 我有鼠标的平移功能可能会干扰保持此代码无法正常工作。 Any Ideas? 有任何想法吗? What could be keeping this from working properly? 有什么可以阻止它正常工作?

SOLVED 解决了

This code worked much better for me than any of the two below: 这段代码对我来说比下面的任何一个都好得多:

Private Sub PictureBox_MouseWheel(sender As System.Object,
                             e As MouseEventArgs) Handles PictureBox1.MouseWheel
    If e.Delta <> 0 Then
        If e.Delta <= 0 Then
            If PictureBox1.Width < 500 Then Exit Sub 'minimum 500?
        Else
            If PictureBox1.Width > 2000 Then Exit Sub 'maximum 2000?
        End If

        PictureBox1.Width += CInt(PictureBox1.Width * e.Delta / 1000)
        PictureBox1.Height += CInt(PictureBox1.Height * e.Delta / 1000)
    End If

End Sub

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 . 它假定存在一个Panel1PictureBox1窗体上( PictureBox1内侧Panel1Panel1.AutoScroll = True与所设定的图像) PictureBox

The code doesn't calculate center point of the zoom, but you can use the e.Location (or eX/eY) for that. 代码不计算缩放的中心点,但您可以使用e.Location(或eX / eY)。

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(): 旧代码 - 工作,但在大的更改中不稳定可能是由于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

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 之前我用过这个: 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 这是一个例子: http//www.dotnetcurry.com/ShowArticle.aspx?ID = 196

I did not check this one, but looks like will work. 我没有检查这个,但看起来会起作用。

I noticed that there's an undesirable effect with the StretchImage SizeMode that ignores the image ratio. 我注意到StretchImage SizeMode会忽略图像比例,这会产生不良影响。 I just added a width and height ratio variable to include in the "zoom" algorithm. 我刚刚添加了宽度和高度比变量,以包含在“缩放”算法中。 See _ratWidth and _ratHeight in code below. 请参阅下面的代码中的_ratWidth_ratHeight

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM