9

我正在使用一组图形覆盖来使用图形对象在图片框控件内绘制图像。我已将 Picturebox 放置在 Panel 内并将 Panel 设置为自动滚动。我现在需要知道如何做的是使用鼠标滚轮以小增量放大图片的大小,同时保持绘制的图像质量。有人知道怎么做吗?

当我使用下面的 Abdias Software 代码进行更新时,当图片框的 Sizemode 属性设置为 StretchImage 时,图片开始变小。我的鼠标具有平移功能,可能会干扰此代码无法正常工作。有任何想法吗?什么可能会阻止它正常工作?

解决了

这段代码对我来说比下面的任何一个都好得多:

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
4

3 回答 3

8

你可以试试这段代码。它假设存在一个Panel1andPictureBox1在表单上(PictureBox1Panel1with内Panel1.AutoScroll = True),并且在 上设置了一个图像PictureBox

该代码不计算缩放的中心点,但您可以为此使用 e.Location(或 eX/eY)。

更新 - 这是(应该)比以前更健壮的新代码(见底部):

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

旧代码 - 有效,但可能由于 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
于 2012-11-21T16:59:45.720 回答
0

基本上,您需要一个图像查看器。我以前用过这个: http ://cyotek.com/blog/creating-a-scrollable-and-zoomable-image-viewer-in-csharp-part-4

效果很好。但是,它是一个用户控件。

对于图片框,您需要从图像创建图形,然后对其进行插值。这是一个例子: http ://www.dotnetcurry.com/ShowArticle.aspx?ID=196

我没有检查这个,但看起来会工作。

于 2012-11-21T15:57:20.493 回答
0

我注意到StretchImage SizeMode忽略图像比例会产生不良影响。我刚刚添加了一个宽度和高度比率变量以包含在“缩放”算法中。请参阅下面_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
于 2015-05-28T19:15:33.193 回答