nobus
asked on
grid over jpg - continued
hello,
i have asked for an add-on here : https://www.experts-exchange.com/questions/28527294/grid-over-jpg-another-add-on.html
it works fine, but i found a drawback ; if i position the fgrid somewhere - and change the # of rows, or Columns, it resets the grid back to 0.
can it be made to stay on the selected coordinates?
i have asked for an add-on here : https://www.experts-exchange.com/questions/28527294/grid-over-jpg-another-add-on.html
it works fine, but i found a drawback ; if i position the fgrid somewhere - and change the # of rows, or Columns, it resets the grid back to 0.
can it be made to stay on the selected coordinates?
Yeah, probably the easiest way to do it:
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
PB.Refresh()
End Sub
Private Sub PB_SizeChanged(sender As Object, e As System.EventArgs) Handles PB.SizeChanged
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
GridOffsetX = e.X
GridOffsetY = e.Y
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
so in case you wonder; the last point is now set directly as the new offset on MouseUp which means the actual point where you release the mouse becomes the exact offset position with the effect of keeping the grid static, pinned to that point as it were, when changing rows/columns afterwards.
couple of notes:
- resize has a funky effect... (may want to put the reset back in for that?)
- the zoomstyle of the picturebox can have the visual effect of changing the actual position of the grid over the picture. If you elaborate on how you do the positioning and if you need to keep that 'static' as well, if needed it would be possible to do the calculations for that.
couple of notes:
- resize has a funky effect... (may want to put the reset back in for that?)
- the zoomstyle of the picturebox can have the visual effect of changing the actual position of the grid over the picture. If you elaborate on how you do the positioning and if you need to keep that 'static' as well, if needed it would be possible to do the calculations for that.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
many thanks - again - Robert!
Open in new window
But like I said in a later comment, without that code the grid appears to jump when sliding it again after changing rows or columns.That could possibly be remedied by remembering (in another global class variable) where you actually positioned the grid last but that would have to be based on the assumption that you actually click on a point of the grid that you want positioned on an exact spot. Then a bit of adding and subtracting should make it possible to reset the offsets (to something other than 0) to make sure that with the new rows/columns setting the grid actually stays put at that point, but only for that point.
EDIT: maybe even simpler by using that last clicked point as grid origin point instead of using offsets.