可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 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 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 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 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