Click here to Skip to main content
14,364,290 members
Rate this:
Please Sign up or sign in to vote.
Hi,

I found this neat little example on scrolling a regular picturebox in vb .net a while ago. I apologize because I can't give credit where credit is due, but it works great for zooming except for one little problem, actually two.

I need to show some info while mousing over the image such as rgb values. The other is to be able to zoom in and change a pixel value like a paint program.

In the example I have a mouseover event in the picturebox that works pretty well to display the rgb value before the image is zooomed in or out. Once the picturebox changes size the rgb is no longer accurate and does not work at all when outside the original picture boundaries.

I can resize the image but the mousewheel zoom works so well I was wondering if anyone could help me make the mouse over event work when the image is zoomed or panned. I have provided a simple project as an example.

Again I apologize to whoever posted this solution, it works great for its original purpose.

Larry

What I have tried:

'Getting screen coordinates and mapping them to the image. Here's the code:

Imports System.ComponentModel

Public Class Form1
    Private ZOOMFACTOR As Double = 1.25

    ' = 25% smaller or larger
    Private MINMAX As Integer = 5
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' PicBox
        ' 
        Me.PicBox.Location = New System.Drawing.Point(120, 120)
        Me.PicBox.Name = "PicBox"
        Me.PicBox.Size = New System.Drawing.Size(PicBox.Image.Width / 3, PicBox.Image.Height / 3)
        Me.PicBox.TabIndex = 3
        Me.PicBox.TabStop = False
        ' 
        ' OuterPanel
        ' 
        Me.OuterPanel.AutoScroll = True
        Me.OuterPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        OuterPanel.Cursor = System.Windows.Forms.Cursors.NoMove2D

        AddHandler OuterPanel.MouseEnter, AddressOf Me.PicBox_MouseEnter
        AddHandler PicBox.MouseEnter, AddressOf Me.PicBox_MouseEnter
        AddHandler OuterPanel.MouseWheel, AddressOf Me.PicBox_MouseWheel
        '   Me.OuterPanel.Controls.Add(Me.PicBox)
        '   Me.OuterPanel.Dock = System.Windows.Forms.DockStyle.Fill
        '   Me.OuterPanel.Location = New System.Drawing.Point(0, 0)
        '  Me.OuterPanel.Name = "OuterPanel"
        Me.OuterPanel.Size = New System.Drawing.Size(210, 190)
        Me.OuterPanel.TabIndex = 4
        ' 
        ' PictureBox
        ' 
        '  Me.Controls.Add(Me.OuterPanel)
        Me.Name = "PictureBox"
        Me.Size = New System.Drawing.Size(1000, 1000)
        Me.OuterPanel.ResumeLayout(False)
        Me.ResumeLayout(False)
    End Sub

    Private Sub PicBox_MouseWheel(sender As Object, e As MouseEventArgs) Handles PicBox.MouseWheel
        If (e.Delta < 0) Then
            Me.ZoomIn()
        Else
            Me.ZoomOut()
        End If
    End Sub

    Private Sub PicBox_MouseEnter(sender As Object, e As EventArgs) Handles PicBox.MouseEnter
        If (Me.PicBox.Focused = False) Then
            Me.PicBox.Focus()
        End If
    End Sub
    Private Sub ZoomIn()
        If ((Me.PicBox.Width _
                    < (Me.MINMAX * Me.OuterPanel.Width)) _
                    AndAlso (Me.PicBox.Height _
                    < (Me.MINMAX * Me.OuterPanel.Height))) Then
            Me.PicBox.Width = Convert.ToInt32((Me.PicBox.Width * Me.ZOOMFACTOR))
            Me.PicBox.Height = Convert.ToInt32((Me.PicBox.Height * Me.ZOOMFACTOR))
            Me.PicBox.SizeMode = PictureBoxSizeMode.StretchImage
        End If

    End Sub

    ''' <summary>
    ''' Make the PictureBox dimensions smaller to effect the Zoom.
    ''' </summary>
    ''' <remarks>Minimum 5 times smaller</remarks>
    Private Sub ZoomOut()
        If ((Me.PicBox.Width _
                    > (Me.OuterPanel.Width / Me.MINMAX)) _
                    AndAlso (Me.PicBox.Height _
                    > (Me.OuterPanel.Height / Me.MINMAX))) Then
            Me.PicBox.SizeMode = PictureBoxSizeMode.StretchImage
            Me.PicBox.Width = Convert.ToInt32((Me.PicBox.Width / Me.ZOOMFACTOR))
            Me.PicBox.Height = Convert.ToInt32((Me.PicBox.Height / Me.ZOOMFACTOR))
        End If

    End Sub

    Private Sub PicBox_MouseMove(sender As Object, e As MouseEventArgs) Handles PicBox.MouseMove
        If PicBox.Image Is Nothing Then
            Exit Sub
        End If
        Dim bmpRGB As Bitmap = PicBox.Image
        Try


            Cursor.Current = Cursors.Hand

            'If e.X > (bmpRGB.Width * CInt(lblZoom.Text) - 1) Or e.Y > (bmpRGB.Height * CInt(lblZoom.Text) - 1) Then Exit Sub
            Dim color = bmpRGB.GetPixel(e.X, e.Y)
            lblColor.Text = "R=: " + color.R.ToString + " G=: " + color.G.ToString + " B=: " + color.B.ToString
            Cursor.Current = Cursors.Default
        Catch
            Cursor.Current = Cursors.Default
        Finally
            '    bmpRGB.Dispose()
            Cursor.Current = Cursors.Default
        End Try
    End Sub
End Class
Posted
Updated 8-Nov-19 22:50pm
Comments
Richard MacCutchan 9-Nov-19 3:44am
   
You should post your question at the article or solution so the person who wrote the code can help you.

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

The problem is that when you zoom an image, you don't affect the underlying Bitmap - you just cause the Paint event to "compress" or "expand" the image before drawing it on the user's screen - which means that the "pixel under the cursor" has no direct relationship with the original image, as it might (for example) be a blend of 9 different image pixels in the original shown as one pixel on the screen if the user is zoomed out. You can get the actual screen pixel value, but it's a little complicated as you need to PInvoke teh system, there is no direct method of accessing the screen other than the spectacularly inefficient "grab a screen bitmap and look at it" approach. See here: api - How to get the colour of a pixel at X,Y using c#? - Stack Overflow[^] and good luck translating it to VB!
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100