How rotate custom moving marker (image) GMap - c#

I have a marker(plane bug) on GMap which moves on a flight path but I want it to rotate when it turns. Is there any way of doing this in GMap C#?

You can use this function to rotate the image of the marker and then just reasign the marker with this image.
public Bitmap RotateImage(Image image, float angle)
{
Bitmap rotatedBmp = new Bitmap(image.Width, image.Height);
rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);
Graphics g = Graphics.FromImage(rotatedBmp);
PointF offset = new PointF(image.Width / 2, image.Height / 2);
g.TranslateTransform(offset.X, offset.Y);
g.RotateTransform(angle);
g.TranslateTransform(-offset.X, -offset.Y);
g.DrawImage(image, new PointF(0, 0));
return rotatedBmp;
}
you can just do it like this then
marker.img = RotateImage(innitialImg, xxx);

Related

Rotate a Gmap marker (bitmap) by any degree in C#

I'm using GMaps for using google maps on c#. I write latitude and langitude values and press the load button. Then the code put a marker(like arrow) that point. I want to rotate that marker for any degree like google maps'. I don't have any sensors so I can write the degree in a textbox and press a rotate button. How can i do that? This code shows how I create markers and put them into my map. I know bitmap a little but not too much and sorry for my bad english. I hope you'll understand what I want.
`double lat = Convert.ToDouble(txtLat.Text);
double lng = Convert.ToDouble(txtLong.Text);
map.Position = new PointLatLng(lat, lng);
//custom marker
Bitmap bmpMarker = (Bitmap)Image.FromFile("img/arrow.png");
PointLatLng point = new PointLatLng(lat, lng);
GMap.NET.WindowsForms.GMapMarker marker = new GMarkerGoogle(point, bmpMarker);
//1. Create a Overlay
GMapOverlay markers = new GMapOverlay("markers");
map.ZoomAndCenterMarkers("markers");
//2. Add all available markers to that Overlay
markers.Markers.Add(marker);
//3. Cover map with Overlay
map.Overlays.Add(markers);
//RotateImage(bmpMarker, 180.0f);
marker.ToolTipText = map.Position.ToString();`
Try to set the Bitmap image again with the rotation because it is not a reference type:
GMap.NET.WindowsForms.GMapMarker marker = new GMarkerGoogle(point, RotateImg(bmpMarker,45));
Suggestion to rotate the bitmap:
public Bitmap RotateImg(Bitmap bmpimage, float angle)
{
int w = bmpimage.Width;
int h = bmpimage.Height;
PixelFormat pf;
pf = bmpimage.PixelFormat;
Bitmap tempImg = new Bitmap(w, h, pf);
Graphics g = Graphics.FromImage(tempImg);
g.DrawImageUnscaled(bmpimage, 1, 1);
g.Dispose();
GraphicsPath path = new GraphicsPath();
path.AddRectangle(new RectangleF(0.0F, 0.0F, w, h));
Matrix mtrx = new Matrix();
mtrx.Rotate(angle);
RectangleF rct = path.GetBounds(mtrx);
Bitmap newImg = new Bitmap(Convert.ToInt32(rct.Width), Convert.ToInt32(rct.Height), pf);
g = Graphics.FromImage(newImg);
g.TranslateTransform(-rct.X, -rct.Y);
g.RotateTransform(angle);
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
g.DrawImageUnscaled(tempImg, 0, 0);
g.Dispose();
tempImg.Dispose();
return newImg;
}

Precision in rotating images

I searched a code to rotate an image in C#, and found this to be almost perfect. It does the job while keeping the same Height and Width properties of my old photo and maintaining its quality.
But, could you improve the code to make it more precise. For example when I send an angle of 0.0001 It doesn't seem to rotate it! (I really need to be so precise in this step)
public static Image RotateImage(Image img, float rotationAngle)
{
Bitmap bmp = new Bitmap(img.Width, img.Height);
turn the Bitmap into a Graphics object
Graphics gfx = Graphics.FromImage(bmp);
gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
gfx.RotateTransform(rotationAngle);
gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.DrawImage(img, new Point(0, 0));
gfx.Dispose();
return bmp;
}

How do you rotate a bitmap an arbitrary number of degrees?

I have a bitmap:
Bitmap UnitImageBMP
And I need to rotate it an arbitrary number of degrees. How do I do this? The RotateFlip method will only rotate in increments of 90 degrees.
I did some searching for you and found this:
public static Bitmap RotateImage(Bitmap b, float angle)
{
//create a new empty bitmap to hold rotated image
Bitmap returnBitmap = new Bitmap(b.Width, b.Height);
//make a graphics object from the empty bitmap
using(Graphics g = Graphics.FromImage(returnBitmap))
{
//move rotation point to center of image
g.TranslateTransform((float)b.Width / 2, (float)b.Height / 2);
//rotate
g.RotateTransform(angle);
//move image back
g.TranslateTransform(-(float)b.Width / 2, -(float)b.Height / 2);
//draw passed in image onto graphics object
g.DrawImage(b, new Point(0, 0));
}
return returnBitmap;
}

Get resulting size of RotateTransform

I've got the following code for rotating an image in C#:
private Bitmap RotateImage(Bitmap b, float angle)
{
//create a new empty bitmap to hold rotated image
Bitmap returnBitmap = new Bitmap(b.Width, b.Height);
//make a graphics object from the empty bitmap
Graphics g = Graphics.FromImage(returnBitmap);
//move rotation point to center of image
g.TranslateTransform((float)returnBitmap.Width / 2, (float)returnBitmap.Height / 2);
//rotate
g.RotateTransform(angle);
//move image back
g.TranslateTransform(-(float)b.Width / 2, -(float)b.Height / 2);
//draw passed in image onto graphics object
g.DrawImage(b, new Rectangle(new Point(0, 0), new Size(b.Width, b.Height)));
return returnBitmap;
}
It works very well, except that it clips the result when it exceeds original bounds.
As I understood, I have to set returnBitmap's size to the size of image after rotation. But how do I find how big the result will be, to set size of the new bitmap accordingly?
You need to rotate the four corners of your original image and calculate the bounding box for the new coordinates:
private static Bitmap RotateImage(Image b, float angle)
{
var corners = new[]
{new PointF(0, 0), new Point(b.Width, 0), new PointF(0, b.Height), new PointF(b.Width, b.Height)};
var xc = corners.Select(p => Rotate(p, angle).X);
var yc = corners.Select(p => Rotate(p, angle).Y);
//create a new empty bitmap to hold rotated image
Bitmap returnBitmap = new Bitmap((int)Math.Abs(xc.Max() - xc.Min()), (int)Math.Abs(yc.Max() - yc.Min()));
...
}
/// <summary>
/// Rotates a point around the origin (0,0)
/// </summary>
private static PointF Rotate(PointF p, float angle)
{
// convert from angle to radians
var theta = Math.PI*angle/180;
return new PointF(
(float) (Math.Cos(theta)*(p.X) - Math.Sin(theta)*(p.Y)),
(float) (Math.Sin(theta)*(p.X) + Math.Cos(theta)*(p.Y)));
}
Pythagoras. It is anywhere from original to sqrt(w^2 + h^2) at 90/270 angle. And I d bet it is determined by sine (max at 90).

How to rotate picturebox

I need to solve a problem by rotating an image, but I have this code to rotate the image does not rotate completely
public static Image RotateImage(Image img, float rotationAngle)
{
//create an empty Bitmap image
Bitmap bmp = new Bitmap(img.Width, img.Height);
//turn the Bitmap into a Graphics object
Graphics gfx = Graphics.FromImage(bmp);
//now we set the rotation point to the center of our image
gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
//now rotate the image
gfx.RotateTransform(rotationAngle);
gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
//set the InterpolationMode to HighQualityBicubic so to ensure a high
//quality image once it is transformed to the specified size
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
//now draw our new image onto the graphics object
gfx.DrawImage(img, new System.Drawing.Point(0, 0));
//dispose of our Graphics object
gfx.Dispose();
//return the image
return bmp;
}
And use this to call method. The right is rotate the image rectangle that contains, and to avoid cutting the image
Bitmap bitmap = (Bitmap)Pix.Image;
Pix.Image = (Bitmap)(RotateImage(bitmap, 20.0f));
private Bitmap RotateImageByAngle(Image oldBitmap, float angle)
{
var newBitmap = new Bitmap(oldBitmap.Width, oldBitmap.Height);
newBitmap.SetResolution(oldBitmap.HorizontalResolution, oldBitmap.VerticalResolution);
var graphics = Graphics.FromImage(newBitmap);
graphics.TranslateTransform((float)oldBitmap.Width / 2, (float)oldBitmap.Height / 2);
graphics.RotateTransform(angle);
graphics.TranslateTransform(-(float)oldBitmap.Width / 2, -(float)oldBitmap.Height / 2);
graphics.DrawImage(oldBitmap, new Point(0, 0));
return newBitmap;
}
I have used in the past the following code from this article.
http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-rotate
Has some other solutions as well.
/// <summary>
/// Rotates the input image by theta degrees around center.
/// </summary>
public static Bitmap rotateCenter(Bitmap bmpSrc, float theta)
{
Matrix mRotate = new Matrix();
mRotate.Translate(bmpSrc.Width / -2, bmpSrc.Height / -2, MatrixOrder.Append);
mRotate.RotateAt(theta, new Point(0, 0), MatrixOrder.Append);
using (GraphicsPath gp = new GraphicsPath())
{ // transform image points by rotation matrix
gp.AddPolygon(new Point[] { new Point(0, 0), new Point(bmpSrc.Width, 0), new Point(0, bmpSrc.Height) });
gp.Transform(mRotate);
PointF[] pts = gp.PathPoints;
// create destination bitmap sized to contain rotated source image
Rectangle bbox = boundingBox(bmpSrc, mRotate);
Bitmap bmpDest = new Bitmap(bbox.Width, bbox.Height);
using (Graphics gDest = Graphics.FromImage(bmpDest))
{ // draw source into dest
Matrix mDest = new Matrix();
mDest.Translate(bmpDest.Width / 2, bmpDest.Height / 2, MatrixOrder.Append);
gDest.Transform = mDest;
gDest.DrawImage(bmpSrc, pts);
//drawAxes(gDest, Color.Red, 0, 0, 1, 100, "");
return bmpDest;
}
}
}
private static Rectangle boundingBox(Image img, Matrix matrix)
{
GraphicsUnit gu = new GraphicsUnit();
Rectangle rImg = Rectangle.Round(img.GetBounds(ref gu));
// Transform the four points of the image, to get the resized bounding box.
Point topLeft = new Point(rImg.Left, rImg.Top);
Point topRight = new Point(rImg.Right, rImg.Top);
Point bottomRight = new Point(rImg.Right, rImg.Bottom);
Point bottomLeft = new Point(rImg.Left, rImg.Bottom);
Point[] points = new Point[] { topLeft, topRight, bottomRight, bottomLeft };
GraphicsPath gp = new GraphicsPath(points,
new byte[] { (byte)PathPointType.Start, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line });
gp.Transform(matrix);
return Rectangle.Round(gp.GetBounds());
}

Categories