Solved

grid over jpg - another add-on

Posted on 2014-09-28
15
222 Views
Last Modified: 2014-10-03
hello,
i asked for a tool placing a grid over a picture here :  http://www.experts-exchange.com/Programming/Languages/CPP/Q_28144750.html

it works fine - but can the chosen grid be slided horizontally and vertically, preferably by mouse dragging ?
0
Comment
Question by:nobus
  • 9
  • 5
15 Comments
 
LVL 40

Expert Comment

by:Vadim Rapp
ID: 40350760
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.
0
 
LVL 92

Author Comment

by:nobus
ID: 40351571
already did that, before posting...
0
 
LVL 35

Accepted Solution

by:
Robert Schutt earned 500 total points
ID: 40351704
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.Controls.Add(TLB)
        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
            Try
                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
            PB.Refresh()
        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
        PB.Refresh()
    End Sub

    Private Sub PB_SizeChanged(sender As Object, e As System.EventArgs) Handles PB.SizeChanged
        GridOffsetX = 0
        GridOffsetY = 0
        PB.Refresh()
    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
            Next
            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
            Next
        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
            PB.Refresh()
        End If
    End Sub

End Class

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 92

Author Comment

by:nobus
ID: 40351903
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?
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40351918
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).
0
 
LVL 92

Author Comment

by:nobus
ID: 40352283
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
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40352323
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.
0
 
LVL 92

Author Comment

by:nobus
ID: 40352338
ok good info.
0
 
LVL 92

Author Comment

by:nobus
ID: 40354018
Robert, another question popped up : where do i place this new code?
before the old one?
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40354043
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
0
 
LVL 92

Author Comment

by:nobus
ID: 40354315
ok i hope i have time today to try it - i would surely love to have this working
0
 
LVL 92

Author Comment

by:nobus
ID: 40354601
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 ?
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40354651
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.
0
 
LVL 92

Author Closing Comment

by:nobus
ID: 40354751
again - many thanks for your effort, and continued support !
Excellent solution
0
 
LVL 92

Author Comment

by:nobus
ID: 40358834
robert, can you also have a look in my next add-on ?

here the link :  http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/Windows_7/Q_28530522.html

thanks in advance!
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Monitor input from a computer is usually nothing special.  In this instance it prevented anyone from using the computer.  This was a preconfiguration that didn't work.
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

685 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question