How to draw a rectangle in WinForm app in the correct location - winforms

I have a WinForm app that has an image displayed in a PictureBox that has the added functionality of allowing a user to draw a rectangle on the image by clicking and dragging.
The Location, Height and Width of the rectangle are saved to disk.
When the image is viewed again I would like to automatically redraw that rectangle in the same position on the image.
When I redraw it, however, the Height and Width are fine but the location is always off.
The location is being captured in the MouseDown Event like so
private void pbSample_MouseDown(object Sender, MouseEventArgs e)
{
if (SelectMode)
{
StartLocation.X = e.X;
StartLocation.Y = e.Y;
//later on these are saved as the location of the rectangle
}
}
And I am redrawing it like so
public void DrawSelectedArea(Rectangle rect)
{
Graphics g = this.pbSample.CreateGraphics();
Pen p = new Pen(Brushes.Black);
g.DrawRectangle(p, rect);
}
Given the location from the MouseEventArgs captured during the MouseDown Event how can I calculate the correct location to redraw my rectangle?

The mouse-click points you're capturing are probably relative to the Form rather than the picture box. You either need to make sure you're capturing the coordinates properly or offset them.
Could you include a screenshot as an example?

Related

How To Draw clickable Polygons

I am developing a winforms project. What I need is, draw a clickable polygon on picturebox. Or draw a polygon and detect click if mouse is in polygon. I can draw a polygon but however I can't discover the click part.
Basically, take coordinates and add to array when I click on panel which has picturebox with image. And draw the polygon when clicked 7 times.
But I don't have a idea how to detect if mouse click is in polygon? Or we can say, how to convert these polygons to buttons?
private void panelPictureBoxBuilding_MouseUp(object sender, MouseEventArgs e)
{
if (startMoving)
{
Point coord = new Point(e.Location.X, e.Location.Y);
coordinates.Add(coord);
if (coordinates.Count == 7)
{
Graphics g = pbBuilding.CreateGraphics();
g.DrawPolygon(Pens.Black, coordinates.ToArray());
}
}
}
EDIT : Also how can i start drawing polygon since first mouse click? Current code is drawing polygon when clicked 7 times.
EDIT2 : I got it. Solution is in the below:
GraphicsPath path = new GraphicsPath(FillMode.Winding);
path.AddPolygon(coordinates.ToArray());
// Its mouse click event, after here
if(path.IsVisible(e.Location.X, e.Location.Y))
{
//Do something
}

How To Get Mouse Click Coordinates Of An Image Inside A Picture Box(Not Picture Box Mouse Click Coordinates But Image Pixel Coordinates)

I have been trying to place a marker at the mouse location on an image when the user clicks on the image box, the problem is that the marker has a certain offset which is exponential, and I think it's because the image size is not equal to the image box size. I also want to place the marker after zooming in on the image.
This is a windows forms project and it uses emgucv, OpenCV, and c++/cli.
Note I place the marker using an OpenCV function by passing the mouse click coordinates.
Can anyone please help?.
I found the solution in this article https://www.codeproject.com/Articles/20923/Mouse-Position-over-Image-in-a-PictureBox you need to translate the PictureBox coordinates to image coordinates however, it depends on the size mode of the PictureBox.
I found a simple way to get mouse click coordinates with respect to a image coordinate when using ImageBox (add Emgu.CV.UI via Nuget). Add MouseClick event to your ImageBox and put that subroutine as below
private void imageBox1_MouseClick(object sender, MouseEventArgs e)
{
var ib = (ImageBox)sender;
var x_offset = ib.HorizontalScrollBar.Value;
var y_offset = ib.VerticalScrollBar.Value;
var x = e.Location.X;
var y = e.Location.Y;
var zoom = ib.ZoomScale;
int X = (int)((x / zoom) + x_offset);
int Y = (int)((y / zoom) + y_offset);
//MessageBox.Show(String.Format("{0}, {1}", X, Y));
}

WPF Thumb DragDelta moving across monitors

I have a Popup control that I added a thumb to so I can drag it around the screen. The thumb's DragDelta event was overloaded with this:
private static void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
Thumb thumb = (Thumb)sender;
Popup popup = thumb.Tag as Popup;
if (popup != null)
{
popup.HorizontalOffset += e.HorizontalChange;
popup.VerticalOffset += e.VerticalChange;
}
}
The Dragging works perfectly (I used the Dragging example from here: http://www.codeproject.com/Articles/43636/WPF-A-search), except for when the popup reaches the end of the monitor and crosses over to the other (dual monitor setup). For instance if I have the popup open on the Left monitor and start dragging it right, when the right border of it touches the edge of the monitor it's movement is erratic and starts moving all around until I move further right and it displays on the other monitor.
I debugged through this scenario, and this is a numerical example of basically what happens:
At edge of screen:
HorizontalOffset = 600
HorizontalChange = 1
Move Right:
HorizontalOffset = 601
HorizontalChange = -800
HorizontalOffset = -199
HorizontalChange = 401
HorizontalOffset = 200
HorizontalChange = -150
Which gives this weird strobe effect of the popup while it moves to the other monitor; Is there something I need to do to get it to transition smoothly across monitors?
I still haven't figured out how to un-bind pop-ups to a screen, but I was able to accomplish what I needed by using the Window control instead. I made WindowStyle.None so there was no border and overloaded the MouseLeftButtonDown event with a delegate to the DragMove() method so they can be dragged around the screen. This allowed me to have very similar look and feel as the pop-ups, but able to drag it around the screen with no flicker.

c# multi - point selection on an image

I'm designing interface with visual c# for my image processing project. I need point selection on an image and classification these points for using in my image processing code at vhdl.
Original image will stay at a picturebox and I will use selected image in another picturebox.
How I can select points on an image?
If you need to get pixel color and coord when mouse is down over picturebox, you could use
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
PictureBox pb = (PictureBox)sender;
Bitmap bmp = (Bitmap)pb.Image;
Color col = bmp.GetPixel(e.X, e.Y);
// Do what you please with pixel coord and color
}

Dynamic drawing of opacity mask

I've got two background pictures, one is blurry, the other one is the same picture, but more colorful.
The default background image is the blurry one.
When I move the cursor, I'd like to change the background image from the blurry to the colorful one,
but only in a circle around the cursor,
and when I move the cursor forward, the changed background stays where the circle around the cursor went earlier.
(like when you scratch a lottery ticket with a coin)
I think I have to handle the MouseMove event, and use the MouseEventArgs cursor position,
but I cannot go through, and I really need help!
Thanks in advance!
You might want to try following this path:
Add a Canvas to your page, with the same size as both of your images
Create a clipping path in the shape of an ellipse (<Ellipse ...>) and position it outside of your image, in the canvas
Put the "blurry image" on your canvas first (below), and then the "sharp image", filling the whole canvas.
Let the ellipse be the clipping mask of your "sharp image" (using Image.Clip or YourUIElement.Clip (reference on MSDN)
Move your ellipse with the mouse cursor. The code might look like this (note: I didn't test the code):
-
imageCanvas.MouseMove += imageCanvas_MouseMove;
private void imageCanvas_MouseMove(object sender, MouseEventArgs e)
{
Point mousePosition = e.GetPosition();
Canvas.SetTop(myEllipse, mousePosition.Y - myEllipse.ActualHeight / 2);
Canvas.SetLeft(myEllipse, mousePosition.X - myEllipse.ActualWidth / 2);
}
If this works, you can increment your visual design adding animations on MouseEnter/MouseLeave, etc.

Resources