问题
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. 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. 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
回答1:
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
回答2:
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.
回答3:
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
来源:https://stackoverflow.com/questions/13496706/how-to-zoom-in-a-picturebox-with-scrollwheel-in-vb-net