In .NET, How can I draw shapes on a picture? - c#

I'm doing a software where I need to put squary bordering fields on a satelite map (.png image), so that the fields can be clicked.
What is the best way to add shapes on a picture and associate them with data ?

Overlay a custom-draw UserControl on top of the Image control. Make part of it transparent to reveal the underlying image, but still be able to capture the mouse interaction.
You will have to calculate the exact position (pixel offset from the map top-left corner) of your control to overlay the proper map area. How you calculate that offset and the actual size of your custom control depends on the map zoom level and whether you use GPS coordinates or image recognition to determine which area needs to be overlayed.

Graphics.FillPolygon()
Is your friend. Hit testing is relatively trivial, with several algorithms available

You want to use the System.Drawing namespace to initially create a graphics object from your source image..then you want to draw on top of it, and finally export your edited graphics object to the filesystem...
Image image = Image.FromFile(Server.MapPath(String.Format("~/{0}.jpg", "YourImageNameHere")));
Graphics MyGraphic = Graphics.FromImage(LabelImage);
MyGraphic.DrawRectangle(SomePenObject, Point1, Point2, Point3, Point4);
Image.Save("C:\somepath.jpg",ImageFormat.Jpeg);

Related

WinRT Bing.Maps - how add a image with a lat/lon bounding box?

I am able to add an image to my map just fine via code.
However when I zoom in/out, the image stays the same. I would like it scale relative to the map.
In the WPF version of the Map, you could use an ImageBrush for a MapPolygon and it would be constrained to the bounding box.
I tried the solution from this SO question, but it seems to have no effect on the Image.
imageLayer.Children.Clear();
MapLayer.SetPosition(_vm.RadarImage, new Location(_vm.Overlay.LatN, _vm.Overlay.LonW));
imageLayer.Children.Add(_vm.RadarImage);
shapeLayer.Shapes.Clear();
var rect = new MapPolygon();
rect.Locations.Add(new Location(_vm.Overlay.LatN, _vm.Overlay.LonW));
rect.Locations.Add(new Location(_vm.Overlay.LatS, _vm.Overlay.LonW));
rect.Locations.Add(new Location(_vm.Overlay.LatS, _vm.Overlay.LonE));
rect.Locations.Add(new Location(_vm.Overlay.LatN, _vm.Overlay.LonE));
rect.FillColor = Colors.Green;
shapeLayer.Shapes.Add(rect);
mappy.SetView(new LocationRect(new Location(_vm.Overlay.LatN + 0.0001, _vm.Overlay.LonW + 0.0001), new Location(_vm.Overlay.LatS - 0.0001, _vm.Overlay.LonE - 0.0001)));
This is the correct scaling.
When you zoom once via the Navigation, you can see the image is now larger than the Polygon
There isn't a simple solution for this. I have put together a sample app that shows one approach to do this. You can find it here: http://code.msdn.microsoft.com/Binding-and-Image-to-a-01a56e48 What I did was add a Canvas to the map, and then use the map to calculate the pixel coordinates of the bounding box for the image. I then used these pixel coordinates to scale and position the image on the canvas overtop the map. I've done something similar to create custom polygons that support image brushes in the past but haven't uploaded that code sample yet.

Crop irregular shape into a rectangle

I'm working on a project that requires the user to select and object from an image. I'm currently doing this by allowing the user to draw a rectangle around the object (the object that needs selecting is always rectangular) I can then crop the selected area. The issue is that in the image the object may not be viewed from a birds eye view and therefore in the image it is not perfectly rectangular.
I have now changed it so the user draws around the objects using lines which works fine but I'm unsure how to crop this irregular shape and then stretch it to fill a rectangle (as I need it to be a perfect rectangle but not have any of the background) some guidance on techniques and where to look would be great. I'm currently using aforge to crop my image.
Thank you
Ok Ive found my solution. I can use aforge SimpleQuadrilateralTransformation Class.
http://www.aforgenet.com/framework/docs/html/15ef1e79-a7ae-93d4-507e-34961c6562ec.htm

Maintaining Graphics Line on Background image in c# panel

I am drawing lines on a background image in a c# panel. The panel is anchored to the form so as the form resizes the panel resizes. The background image is set to be stretched so all you see as you resize the form is the background image.
My initial problem:
The lines drawn on the panel (via the OnPaint event) stay where they were originally drawn as the image resizes.
My current solution:
Record the location of the line and redraw it on a new bitmap by scaling the X and Y coordinates (works fine).
My new problem:
As you continually resize the window and draw lines you can't calculate the scaling factor from any point in time and apply it to all lines since the lines were originall drawn in different size images.
The two options I think I have:
After I redraw the line go through my array of lines and update the coordinate information so it now matches the current scale.
Or
In addition to storing the coordinate information of the line also store the size information of the panel at the time it was drawn so I can always calculate the scale for each line based on when it was drawn and the new panel size.
What I'm hoping for:
If you have thoughts on either of the two approaches that would be greatly appreciated....Even better would be to point me in the direction of a far better method to do this (I am fairly new to graphics processing in c#).
Can't write a comment, much as I want to. You do have a few options:
Draw your lines directly on the original Bitmap. This might not be an option for you, depending on the task.
Do it as you're doing now, keeping track of the lines' coordinates, updating them on resize, and redrawing them on Paint - if you use this, you'll be able to move and delete them, too,
Or do it by introducing a "scale factor" (float) which you update on every resize, and in your Paint event handler you draw everything using that scale factor. As you create a line, you calculate its coordinates using the scale factor BACK TO an unified coordinate system (scale factor 1) and then you don't have to modify your coordinates at all. This might be easy to debug due to that unified coordinate system. This is what I'd recommend, but it again depends on your task.
Draw to a full transparent Bitmap of the same size as your original image, use a scale factor like in the previous option. On creating a line, calculate its coordinates in the unified coordinate system, draw it on the Bitmap, and then on every Paint, draw the entire Bitmap over your original one. This, again, might not be an option if you need to delete or move your lines, or if you're tight on memory, or you don't want your lines to be blurred when you scale up, but somehow many ppl like this because it's like a "layer in Photoshop". :)

How to get (x, y) coordinates of displayed image?

Currently, I'm using a WPF Image control to display images. I want to do the following: On a MouseUp, MouseDown or MouseMove event, I want to get the coordinates of the point under the cursor, not with reference to the top-left corner of the control, but with respect to the actual coordinates of the displayed bitmap, which may have been re-scaled, or may have a different aspect ratio than the control itself. If an alternate control provides this functionality, I'd be equally happy to hear about it. Thanks in advance.
EDIT: I'd also like so may to know it if the coordinates of the control were out of range of the image, due to a different aspect ratio.
you can get the coordinates of the mouse by this way :
private void image1_MouseDown(object sender, MouseButtonEventArgs e)
{
Point point = e.GetPosition(image1); //position relative to the image
Point point2 = e.GetPosition(this); //position relative to the window
}
Hope that answered a part of your question.
You can use the various TransformTo* methods of the Visual class to get, coordnates relative to a sepcific control, it will take all transformation applied to the visual tree into account.
Also, if you attach MouseUp, MouseDown and MouseMove to the Image control itself, you should already get the correct coordinates from the MouseButtonEventArgs and if you use the mouse outside of the visual bounds of the control, you will not get those events, so you don't need extra code check for coordinates being out of bounds.
If your actual goal is to find out which acutal pixel of your bitmap image has been touched by the mouse (as you would need for a bitmap/pixel editing software) things get much harder because WPF uses virtual device indendent pixels that do not directly relate to pixels on the screen or pixels in a bitmap that has been rendered in an Image control. The Image control internally scales a bitmap image based on the DPI settings of the bitmap file itself and based on the DPI settings of operating system.

MonoTouch/Objective-C - Detect How Much of a UIImageView is Currently Visible

I have a UIImageView as a subview of a UIScrollView, the image view is filled using a CGBitmapContext which is drawn to using a DrawTileAtIndex method.
In order to increase performance, I would only like to draw those tiles that are visible, is there any way I can detect how much of my UIImageView is currently visible to the user? I.E What area, pixels etc If so, how do I detect this in order to draw the correct tiles?
CATiledLayer is not an option.
Thanks in advance,
Jack
Assuming you have an image that is larger than can be viewed at any one time, then create a UIView subclass with the image as a property. When you are sent drawRect:, then you can use the passed in rect to test your tiles against, and only those tiles that overlap that rect need to be drawn.
You can use the 'CGRectIntersectsRect' function to do the test.

Categories

Resources