grid over jpg - another add-on

i asked for a tool placing a grid over a picture here :

it works fine - but can the chosen grid be slided horizontally and vertically, preferably by mouse dragging ?
LVL 95
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Vadim RappCommented:
I would click on the nick of the expert whose solution you accepted in that thread, and contacted him with the request to code the enhancement.

In fact, since he practically wrote for you a little project already, while the goal of E-E is to help you to write it on your own, I would have sent a contribution to the beer fund he mentions in his profile, already after that question.
nobusAuthor Commented:
already did that, before posting...
Robert SchuttSoftware EngineerCommented:
Well, beer fund or not, you can never know of course if a specific expert is available at the moment. I would understand if you want to keep this open to see what Idle_Mind comes up with but here's my solution for this, based on the last code posted in the referred question:
Public Class Form1

    Private GridColor As Color = Color.Black
    ' additional members for grid offset
    Private GridOffsetX As Integer = 0
    Private GridOffsetY As Integer = 0
    Private GridOffsetPrvX As Integer = -1
    Private GridOffsetPrvY As Integer = -1
    Private GridMoving As Boolean = False

    Private WithEvents PB As New PictureBox
    Private WithEvents Rows As New NumericUpDown
    Private WithEvents Cols As New NumericUpDown
    Private WithEvents btnSelectFile As New Button
    Private WithEvents btnSelectColor As New Button

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Rows.Minimum = 2
        Cols.Minimum = 2

        Dim TLB As New TableLayoutPanel
        TLB.RowCount = 2
        TLB.RowStyles.Add(New RowStyle(SizeType.AutoSize))
        TLB.RowStyles.Add(New RowStyle(SizeType.Percent, 100))
        TLB.ColumnCount = 6
        TLB.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 20))
        TLB.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 20))
        TLB.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 20))
        TLB.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 20))
        TLB.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 20))
        TLB.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 20))

        Dim lbl As New Label
        lbl.Text = "Rows:"
        lbl.TextAlign = ContentAlignment.TopRight
        lbl.Dock = DockStyle.Bottom
        TLB.Controls.Add(lbl, 0, 0)
        TLB.Controls.Add(Rows, 1, 0)

        lbl = New Label
        lbl.Text = "Cols:"
        lbl.TextAlign = ContentAlignment.TopRight
        lbl.Dock = DockStyle.Bottom
        TLB.Controls.Add(lbl, 2, 0)
        TLB.Controls.Add(Cols, 3, 0)

        btnSelectFile.Text = "Pic"
        btnSelectFile.AutoSize = True
        btnSelectFile.Dock = DockStyle.Fill
        TLB.Controls.Add(btnSelectFile, 4, 0)

        btnSelectColor.Text = "Color"
        btnSelectColor.AutoSize = True
        btnSelectColor.Dock = DockStyle.Fill
        TLB.Controls.Add(btnSelectColor, 5, 0)

        PB.Dock = DockStyle.Fill
        PB.SizeMode = PictureBoxSizeMode.Zoom
        PB.BorderStyle = BorderStyle.FixedSingle
        TLB.Controls.Add(PB, 0, 1)
        TLB.SetColumnSpan(PB, 6)

        TLB.Dock = DockStyle.Fill
        Me.Text = "Image Grid Tool"
    End Sub

    Private Sub btnSelectFile_Click(sender As Object, e As System.EventArgs) Handles btnSelectFile.Click
        Static OFD As New OpenFileDialog
        OFD.Title = "Select an Image File"
        OFD.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*"
        If OFD.ShowDialog = Windows.Forms.DialogResult.OK Then
                PB.Image = New Bitmap(Image.FromFile(OFD.FileName))
            Catch ex As Exception
                MessageBox.Show("File: " & OFD.FileName & vbCrLf & vbCrLf & ex.ToString, "Error Opening Image", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End If
    End Sub

    Private Sub btnSelectColor_Click(sender As Object, e As System.EventArgs) Handles btnSelectColor.Click
        Static CD As New ColorDialog
        If CD.ShowDialog = Windows.Forms.DialogResult.OK Then
            GridColor = CD.Color
        End If
    End Sub

    Private Sub Rows_Cols_ValueChanged(sender As Object, e As System.EventArgs) Handles Rows.ValueChanged, Cols.ValueChanged
        GridOffsetX = 0
        GridOffsetY = 0
    End Sub

    Private Sub PB_SizeChanged(sender As Object, e As System.EventArgs) Handles PB.SizeChanged
        GridOffsetX = 0
        GridOffsetY = 0
    End Sub

    Private Sub PB_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles PB.Paint
        Using pn As New Pen(GridColor)
            Dim xValue, yValue As Integer
            For y As Integer = 1 To Rows.Value
                yValue = (y / Rows.Value * PB.Height + GridOffsetY) Mod PB.Height
                If yValue > 0 And yValue < PB.Height - 3 Then ' don't draw line right up against top or bottom border
                    e.Graphics.DrawLine(pn, 0, yValue, PB.Width, yValue)
                End If
            For x As Integer = 1 To Cols.Value
                xValue = (x / Cols.Value * PB.Width + GridOffsetX) Mod PB.Width
                If xValue > 0 And xValue < PB.Width - 3 Then ' don't draw line right up against left or right border
                    e.Graphics.DrawLine(pn, xValue, 0, xValue, PB.Height)
                End If
        End Using
    End Sub

    Private Sub PB_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PB.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            GridMoving = True
            GridOffsetPrvX = e.X
            GridOffsetPrvY = e.Y
        End If
    End Sub

    Private Sub PB_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PB.MouseUp
        GridMoving = False
    End Sub

    Private Sub PB_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PB.MouseMove
        If GridMoving Then
            GridOffsetX += e.X - GridOffsetPrvX
            GridOffsetY += e.Y - GridOffsetPrvY
            ' keep it positive for the 'mod' to work in PB_Paint
            While GridOffsetX < 0
                GridOffsetX += PB.Width
            End While
            While GridOffsetY < 0
                GridOffsetY += PB.Height
            End While
            ' remember new position for next move
            GridOffsetPrvX = e.X
            GridOffsetPrvY = e.Y
        End If
    End Sub

End Class

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

nobusAuthor Commented:
Robert, tx for posting; can you explain what this will do?
i suppose from the code you put in a piece enabling dragging the grid with mouse - correct?
Robert SchuttSoftware EngineerCommented:
Yes, I added some class members to store settings like "are we currently dragging" and the actual offsets (lines 4-9). Then in the existing event handlers where the rows/columns are changed and the picturebox is resized I reset the offsets (lines 90,91 & 96,97) because otherwise some 'jumping around' occurs (as the offsets no longer match the position where the lines are drawn). I also made some changes to PB_Paint to account for the offset when drawing the grid (lines 104-115). And finally I added event handlers for mouse actions on the picturebox that actually record the changing offset where you want the grid to go (lines 119-149).
nobusAuthor Commented:
ok seems fine to me.
on what systems does it work?  XP, vista, Win7, 8, 32-64 bit - any restrictions there?
anyway, i'll be testing it tomorrow
Robert SchuttSoftware EngineerCommented:
There should be no restrictions, just make sure your project targets "any cpu" if you want to profit from 64 bit assemblies on 64 bit systems. Not sure if you'd notice anything in this case, like faster jpeg decompression or 'paint' refresh rate for example. I even read somewhere that in certain cases 64 bit executables are slower maybe because they can't utilize 64 bit addressing on most systems anyway, but I'm guessing now.

And possibly the other way around: set your project target to 32 bit (x86) if you need an XP exe specifically. I only tested on Windows 7 32 bit though.

Another thing I'm not sure about regarding XP is what .NET framework versions it supports. So you could 'dial back' the default (4.0/4.5?) in your project (to 3.5 or even 2.0) if necessary but you'd better check a system you're planning to use this on.
nobusAuthor Commented:
ok good info.
nobusAuthor Commented:
Robert, another question popped up : where do i place this new code?
before the old one?
Robert SchuttSoftware EngineerCommented:
No, like in the previous question, it's a complete replacement. Click "Select all" below the code I posted here and copy the code. Then open your project and go the code for Form1, select all of the class code and paste the new code over it. Alternatively, if you have made changes to the code, review the lines I referred to in my previous post, find them and change them accordingly. If you have a WinDiff sort of program you could save the new code in a text file and compare to your existing Form1.vb, skipping the obvious addition at the beginning of the code you should see something like this:
capture diff
nobusAuthor Commented:
ok i hope i have time today to try it - i would surely love to have this working
nobusAuthor Commented:
it does what i want, so i'll close this now
Many thanks

how is it possible to create that as fast as you did - if you don't mind telling me ?
Robert SchuttSoftware EngineerCommented:
Fast? There's more than 24 hours between your question and my first post ;-)

But I guess it took about 2 hours, including some failed attempts trying to keep it all in 1 function using static variables.

Also quite a bit of testing/debugging because as you can see in the code, I found that a negative offset caused a problem with the "mod" so made a change for that, then I found that changing the rows/columns caused the grid to jump so I added the "reset offset". Then I found that grid lines being drawn at the edges caused an ugly double border so I decided to fix that before posting. Little things but still...

So it was more a question of thinking about how to test and refine the additions to the code rather than coming up with the initial implementation. Similar functionality has been part of implementations I did in the past and a global idea of how to do it immediately came to mind while first reading your question (I mean using MouseMove and offset). Of course that comes with the territory when you've been practically glued to a keyboard since about 1980 ;-) But I'm sure many developers with only a couple of years of experience would think of a similar solution pretty quick.
nobusAuthor Commented:
again - many thanks for your effort, and continued support !
Excellent solution
nobusAuthor Commented:
robert, can you also have a look in my next add-on ?

here the link :

thanks in advance!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.