none
Zooming image in a PictureBox control causes the PictureBox to move on the form RRS feed

  • Question

  • Hello, all.  When dinosaurs ruled the Earth and Windows NT 4 was "new technology", I was an MCSE and a programmer in VB6.  I've moved to other things in life (I've not done any real coding in about 5 years and that was in VB6) but decided to write a specific program for myself and, wow, hasn't the technology changed a bunch?  Visual Studio Visual Basic 2017 is not VB6.  I say all that about my past to explain how I understand a lot of this stuff (form width, height, pixels, variables, subs and so forth), and yet cannot get some simple stuff to work properly.

    I put a PictureBox control on a form and grabbed some code here to zoom the displayed image based on the MouseWheel event.  What happens, though, is that as I zoom in and out, the Left position of the PictureBox changes.  I update the titlebar with the left and right positions and it indicates "30 - 30" at each update of the zoom, but the image (PictureBox) moves from left to right as I zoom in and out.

    I've checked the Form width and height; they do not change during the zoom operations.  I've checked the PictureBox width and height and they do change.  Since we're measuring from the left and the top for the properties of the PictureBox, I would think the box would just get taller and wider, but keep the same distance from the left and the top of the form.

    Can someone tell me if I'm doing something stupid, please?  Thank you.

    Here's zoom code:

    Private Sub PictureBox1_MouseWheel(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseWheel
            If e.Delta <> 0 Then
                If e.Delta <= 0 Then
                    If PictureBox1.Width < 250 Then Exit Sub 'minimum 50?
                Else
                    If PictureBox1.Width > 1000 Then Exit Sub 'maximum 500?
                End If
                PictureBox1.Width += CInt(PictureBox1.Width * e.Delta / 1000)
                PictureBox1.Height += CInt(PictureBox1.Height * e.Delta / 1000)

                PictureBox1.Left = PictureBoxLeft
                PictureBox1.Top = PictureBoxTop

                Me.Text = CStr(PictureBox1.Left) & " - " & CStr(PictureBox1.Top)
                'Me.Text = CStr(PictureBox1.Width) & " - " & CStr(PictureBox1.Height)
                'Me.Text = CStr(Me.Width) & " - " & CStr(Me.Height)

            End If

    Saturday, April 28, 2018 10:31 PM

All replies

  • Where does (PictureBoxLeft) get set in your code.  That seems to be the only part I see in that code that sets the Left location of PictureBox1.  Have you tried just setting that to a fixed value to see if it moves?

     PictureBox1.Left = PictureBoxLeft
    
    'maybe just try a fixed value to test it and see if it moves...
    
     PictureBox1.Left = 10 'or whatever number


    If you say it can`t be done then i`ll try it

    Saturday, April 28, 2018 10:49 PM
  • Hello, all.  When dinosaurs ruled the Earth and Windows NT 4 was "new technology", I was an MCSE and a programmer in VB6.  I've moved to other things in life (I've not done any real coding in about 5 years and that was in VB6) but decided to write a specific program for myself and, wow, hasn't the technology changed a bunch?  Visual Studio Visual Basic 2017 is not VB6.  I say all that about my past to explain how I understand a lot of this stuff (form width, height, pixels, variables, subs and so forth), and yet cannot get some simple stuff to work properly.

    I put a PictureBox control on a form and grabbed some code here to zoom the displayed image based on the MouseWheel event.  What happens, though, is that as I zoom in and out, the Left position of the PictureBox changes.  I update the titlebar with the left and right positions and it indicates "30 - 30" at each update of the zoom, but the image (PictureBox) moves from left to right as I zoom in and out.

    I've checked the Form width and height; they do not change during the zoom operations.  I've checked the PictureBox width and height and they do change.  Since we're measuring from the left and the top for the properties of the PictureBox, I would think the box would just get taller and wider, but keep the same distance from the left and the top of the form.

    Can someone tell me if I'm doing something stupid, please?  Thank you.

    Here's zoom code:

    Private Sub PictureBox1_MouseWheel(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseWheel
            If e.Delta <> 0 Then
                If e.Delta <= 0 Then
                    If PictureBox1.Width < 250 Then Exit Sub 'minimum 50?
                Else
                    If PictureBox1.Width > 1000 Then Exit Sub 'maximum 500?
                End If
                PictureBox1.Width += CInt(PictureBox1.Width * e.Delta / 1000)
                PictureBox1.Height += CInt(PictureBox1.Height * e.Delta / 1000)

                PictureBox1.Left = PictureBoxLeft
                PictureBox1.Top = PictureBoxTop

                Me.Text = CStr(PictureBox1.Left) & " - " & CStr(PictureBox1.Top)
                'Me.Text = CStr(PictureBox1.Width) & " - " & CStr(PictureBox1.Height)
                'Me.Text = CStr(Me.Width) & " - " & CStr(Me.Height)

            End If

    Hi

    Using this (based on your code), seems not to show the effect you mention. In fact, I couldn't get anything to show that effect.

      Private Sub PictureBox1_MouseWheel(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseWheel
    
        PictureBox1.Width += CInt(PictureBox1.Width * e.Delta / 1000)
        PictureBox1.Height += CInt(PictureBox1.Height * e.Delta / 1000)
    
        Text = CStr(PictureBox1.Left) & " - " & CStr(PictureBox1.Top) & " - " & CStr(PictureBox1.Width)
      End Sub


    Regards Les, Livingston, Scotland

    Saturday, April 28, 2018 10:53 PM
  • I put a PictureBox control on a form and grabbed some code here to zoom the displayed image based on the MouseWheel event.  What happens, though, is that as I zoom in and out, the Left position of the PictureBox changes.

    If the image is repositioned within the picture box control, that is associated with the SizeMode property.   As the size of the picture box is changed the relative position of the image within the picture box is recalculated according to that setting.

    If you don't want the image to move within the picture box control then you need to create an image that fills the control by cropping the portion of the original image to exactly what you want to show.  Then use a size mode setting of Normal.

    Saturday, April 28, 2018 10:54 PM
  • Set the PictureBox to have single or 3d borders so you can see if the borders are moving. I don't see how in your code that the PictureBox would move at all.

    Nor do I understand how you believe enlarging the PictureBox will zoom the image.

    If the image is a BackgroundImage in the PictureBox and the PictureBox's BackgroundImageLayout is set to zoom then as the PictureBox gets larger and smaller so will the image but you don't display code for those properties.

    Perhaps there is other code in a paint event for the PictureBox altering its location. Is that all the code you have that sets the top and left of the PictureBox?


    La vida loca

    Saturday, April 28, 2018 11:15 PM
  • Thanks for the reply, IronRazerz.

    <deleted irrelevant reply from me>

    Okay, in the process of replying to you and testing it your way, just in case...I thought about how to show you and others what I was dealing with.  For grins, I put a border around the PictureBox and tried the zoom in and out.  It stayed fixed at the upper left.  Hmmmm, loaded an image in the Box and, BAM! it was centered.  The PictureBox was sized according to the height of the image and maintaining the aspect ratio for the left and right meaning it had a huge curtain on each side.  DOH!

    The PictureBox control is staying where it's supposed to, the image just gets a larger column box (?) on each size (it's a Portrait-shaped image).

    Thanks again for your reply.  You helped me work it through.  I just need to size the control differently.

    --HC

    Sunday, April 29, 2018 12:35 AM
  • There are lots of ways to do things of course.

    Here is an example that centers mouse wheel zooming at the current mouse pointer position and you can also drag the image with LMB.

    Do that in vb6!   :)

    Public Class Form7
        Private WithEvents Pic1 As New PictureBox With {.Parent = Me, .Dock = DockStyle.Fill}
        Private Corner As New PointF(0, 0)
        Private MouseDownPt, MouseMovePt, MouseDownCornerPt As New PointF
        Private SourcePic As New Bitmap("c:\bitmaps\rusty.jpg")
        Private ScaleWidth As Double = SourcePic.Width
        Private ScaleRatio As Double
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
            Text = "MW Zoom - LMB Drag"
            Form2_Resize(0, Nothing)
        End Sub
    
        Private Sub Form2_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            SetScaleRatio(New MouseEventArgs(0, 0, 0, 0, 0))
            Pic1.Invalidate()
        End Sub
    
        Private Sub Pic1_Paint(sender As Object, e As PaintEventArgs) Handles Pic1.Paint
    
            With e.Graphics
                .Clear(Color.White)
                .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
    
                Dim sf As Single = CSng(Pic1.ClientRectangle.Width / ScaleWidth)
                .ScaleTransform(sf, sf)
                .TranslateTransform(-Corner.X, -Corner.Y)
    
                .DrawImage(SourcePic, New Rectangle(0, 0, SourcePic.Width, SourcePic.Height))
    
            End With
        End Sub
    
        Private Sub Pic1_MouseDown(sender As Object, e As MouseEventArgs) Handles Pic1.MouseDown
            MouseDownPt = e.Location
            MouseMovePt = e.Location
            MouseDownCornerPt = Corner
        End Sub
    
        Private Sub Pic1_MouseMove(sender As Object, e As MouseEventArgs) Handles Pic1.MouseMove
            MouseMovePt = e.Location
    
            If e.Button = MouseButtons.Left Then
                'drag the screen
                Dim sf As Double = Pic1.ClientSize.Width / ScaleWidth
                Dim x As Integer = CInt(MouseDownCornerPt.X - ((MouseMovePt.X - MouseDownPt.X) / sf))
                Dim y As Integer = CInt(MouseDownCornerPt.Y - ((MouseMovePt.Y - MouseDownPt.Y) / sf))
                Corner = New Point(x, y)
                Pic1.Invalidate()
            End If
        End Sub
    
        Private Sub Pic1_MouseWheel(sender As Object, e As MouseEventArgs) Handles Pic1.MouseWheel
            SetScaleRatio(e)
            Pic1.Invalidate()
        End Sub
    
        Private Sub Pic1_MouseEnter(sender As Object, e As EventArgs) Handles Pic1.MouseEnter
            If Not Pic1.Focused Then Pic1.Focus()
        End Sub
    
        Private Sub SetScaleRatio(e As MouseEventArgs)
            Dim x, y, s2 As Double
            Dim w As Double = ClientSize.Width
            Dim s As Double = CSng(ScaleWidth)
    
            If ScaleRatio <> 0 Then
                'calc mouse position in scaleunits
                x = Corner.X + (e.X * ScaleRatio)
                y = Corner.Y + (e.Y * ScaleRatio)
    
                'calc new scale and view centered on mouse position
                s2 = s - (Math.Sign(e.Delta) * s / 12)
                ScaleRatio = s2 / w
                ScaleWidth = s2
                Corner.X = CSng(x - (e.X * ScaleRatio))
                Corner.Y = CSng(y - (e.Y * ScaleRatio))
            Else
                ScaleRatio = s / w
            End If
        End Sub
    End Class


    • Edited by tommytwotrain Sunday, April 29, 2018 12:41 AM
    • Proposed as answer by Stanly Fan Monday, April 30, 2018 7:12 AM
    Sunday, April 29, 2018 12:36 AM
  • There are lots of ways to do things of course.

    Here is an example that centers mouse wheel zooming at the current mouse pointer position and you can also drag the image with LMB.

    Do that in vb6!   :)



    Nice. Now if only you could draw the mouse wheel rotating as you can draw the Cursor and circle on mouse down for dragging! ;)

    La vida loca

    Sunday, April 29, 2018 1:47 AM
  • First, thanks for your reply.

    Second, I left out a bit of code which seems to make it work which would be:

    Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
            PictureBox1.Select()  'probably deselect in leave
        End Sub

    Finally, I found the problem to be that the PictureBox shows the image in Portrait format including "empty" bars on the right and left.  What I was seeing was the image appear to move because the blank columns on either side were changing size.  Putting a box (BorderStyle = FixedSingle) around the PictureBox showed this.

    The PictureBox was staying where it was supposed to.

    Thanks again.

    --HC

    Sunday, April 29, 2018 4:06 AM
  • Thanks for the reply.  Yes, the image was repositioned in the PictureBox.  The image, in a Portrait layout, had deadspace left and right which scaled and appeared to make the control move.  I put a border around the PictureBox control and found this.  Oops.  My bad.

    --HC

    Sunday, April 29, 2018 4:11 AM
  • LaVidaLoca, yes, the borders helped.  In my attempts to reply to the first responder's post, I found this.  The border showed me that the control was not moving, just the deadspace "curtains" were changing size, too.

    --HC

    Sunday, April 29, 2018 4:14 AM
  • LaVidaLoca, yes, the borders helped.  In my attempts to reply to the first responder's post, I found this.  The border showed me that the control was not moving, just the deadspace "curtains" were changing size, too.

    --HC

    HC,

    If your question has been answered then please close the thread by selecting the post(s) that helped using the Select as Answer link at the bottom of the post. Mark any helpful posts you liked as well.

    Furthermore, There are settings which affect how the image is placed on the picturebox ie Zoom, Stretch. You will see different results depending on the setting.

    https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k%28System.Windows.Forms.Control.BackgroundImageLayout%29%3Bk%28TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5.2%29%3Bk%28DevLang-VB%29&rd=true&f=255&MSPPError=-2147217396

    https://msdn.microsoft.com/en-us/library/system.windows.forms.imagelayout(v=vs.110).aspx

    • Proposed as answer by Stanly Fan Wednesday, May 2, 2018 1:28 AM
    Sunday, April 29, 2018 2:16 PM
  • Nice. Now if only you could draw the mouse wheel rotating as you can draw the Cursor and circle on mouse down for dragging! ;)

    La vida loca

     That would be my department.  That circle is drawn by my Gif Creator program when a mouse button is detected as being pressed while the screen capture method is capturing the screen.  Maybe at some point I will try using a different method to handle the mouse activity better.  Maybe even add keyboard activity too.  I just have too much stuff to keep up with at this point in time.   8)


    If you say it can`t be done then i`ll try it

    Sunday, April 29, 2018 5:15 PM