Solved

grid over jpg - another add-on

Posted on 2014-09-28
15
206 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 91

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
 
LVL 91

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 91

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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 91

Author Comment

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

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 91

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 91

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 91

Author Closing Comment

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

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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
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…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

743 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now