C# 在旋转c后找到图像中的原点#
下面的图片说明了我正在尝试做什么 我正在旋转c#(白色矩形)中的图像。 问题是,我需要将绿色正方形(另一个图像)放置在相对于矩形的同一点上,而不考虑旋转。绿色正方形不能与矩形一起旋转 正如你们所看到的,在白色矩形旋转之后,每次我都会得到不同大小的画布 我试图找到一个确切的点,以放置绿色正方形后,新的旋转图像创建 下面是一些旋转图像并将圆点放置在正确位置的代码。 现在的问题是,如果我在RotateImage方法中应用变换,我会看到所有的矩形,但很明显,我的红点在错误的位置。 我应该强调的是,我需要知道圆点的位置,而不仅仅是把它放在正确的位置C# 在旋转c后找到图像中的原点#,c#,image,rotation,point,C#,Image,Rotation,Point,下面的图片说明了我正在尝试做什么 我正在旋转c#(白色矩形)中的图像。 问题是,我需要将绿色正方形(另一个图像)放置在相对于矩形的同一点上,而不考虑旋转。绿色正方形不能与矩形一起旋转 正如你们所看到的,在白色矩形旋转之后,每次我都会得到不同大小的画布 我试图找到一个确切的点,以放置绿色正方形后,新的旋转图像创建 下面是一些旋转图像并将圆点放置在正确位置的代码。 现在的问题是,如果我在RotateImage方法中应用变换,我会看到所有的矩形,但很明显,我的红点在错误的位置。 我应该强调的是,我需
public class IconController : Controller
{
//
// GET: /Icon/
public ActionResult Index()
{
return View();
}
////Icon/Icon?connected=true&heading=320&type=logo45
public ActionResult Icon(bool connected, float heading, string type)
{
var dir = Server.MapPath("/images");
//RED SQUARE IM TRYING TO PLACE ON THE BLUE RECTANGLE.
var path = Path.Combine(dir, "mapicons/center.png");
//GREEN RECTANGLE WITH FIXED YELLOW (Actual center) AND BLUE (point im really trying to find)
var path2 = Path.Combine(dir, "mapicons/connected-marker.png");
Image innerIcon = Image.FromFile(path);
Image marker = Image.FromFile(path2);
using (marker)
{
Point orginalCenter = new Point((marker.Width / 2), (marker.Height / 2));
Bitmap markerbitmap = RotateImage(new Bitmap(marker), heading);
marker = (Image)markerbitmap;
using (var bitmap = new Bitmap(marker.Width, marker.Height))
{
using (var canvas = Graphics.FromImage(bitmap))
{
PointF newCenter = RotatePoint(orginalCenter, 80, 120, heading, marker.Width, marker.Height);
canvas.DrawRectangle(new Pen(Color.Black), 0, 0, bitmap.Width, bitmap.Height);
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.DrawImage(marker, new Rectangle(0, 0, marker.Width, marker.Height), new Rectangle(0, 0, marker.Width, marker.Height), GraphicsUnit.Pixel);
canvas.DrawImage(innerIcon, newCenter.X - (innerIcon.Width / 2), newCenter.Y - (innerIcon.Height / 2));
canvas.Save();
}
try
{
bitmap.Save(Path.Combine(dir, "result.png"), ImageFormat.Png);
path = Path.Combine(dir, "result.png");
}
catch (Exception ex) { }
}
}
return base.File(path, "image/png");
}
public static Bitmap RotateImage(Bitmap b, float Angle)
{
// The original bitmap needs to be drawn onto a new bitmap which will probably be bigger
// because the corners of the original will move outside the original rectangle.
// An easy way (OK slightly 'brute force') is to calculate the new bounding box is to calculate the positions of the
// corners after rotation and get the difference between the maximum and minimum x and y coordinates.
float wOver2 = b.Width / 2.0F;
float hOver2 = b.Height / 2.0F;
float radians = -(float)(Angle / 180.0 * Math.PI);
// Get the coordinates of the corners, taking the origin to be the centre of the bitmap.
PointF[] corners = new PointF[]{
new PointF(-wOver2, -hOver2),
new PointF(+wOver2, -hOver2),
new PointF(+wOver2, +hOver2),
new PointF(-wOver2, +hOver2)
};
for (int i = 0; i < 4; i++)
{
PointF p = corners[i];
PointF newP = new PointF((float)(p.X * Math.Cos(radians) - p.Y * Math.Sin(radians)), (float)(p.X * Math.Sin(radians) + p.Y * Math.Cos(radians)));
corners[i] = newP;
}
// Find the min and max x and y coordinates.
float minX = corners[0].X;
float maxX = minX;
float minY = corners[0].Y;
float maxY = minY;
for (int i = 1; i < 4; i++)
{
PointF p = corners[i];
minX = Math.Min(minX, p.X);
maxX = Math.Max(maxX, p.X);
minY = Math.Min(minY, p.Y);
maxY = Math.Max(maxY, p.Y);
}
// Get the size of the new bitmap.
SizeF newSize = new SizeF(maxX - minX, maxY - minY);
// ...and create it.
Bitmap returnBitmap = new Bitmap((int)Math.Ceiling(newSize.Width), (int)Math.Ceiling(newSize.Height));
// Now draw the old bitmap on it.
using (Graphics g = Graphics.FromImage(returnBitmap))
{
g.TranslateTransform(newSize.Width / 2.0f, newSize.Height / 2.0f);
g.RotateTransform(Angle);
g.TranslateTransform(-b.Width / 2.0f, -b.Height / 2.0f);
g.DrawImage(b, 0, 0);
}
return returnBitmap;
}
public static Point RotatePoint(Point pointToRotate, Point centerPoint, double angleInDegrees)
{
double angleInRadians = angleInDegrees * (Math.PI / 180);
double cosTheta = Math.Cos(angleInRadians);
double sinTheta = Math.Sin(angleInRadians);
Point pt = new Point();
pt.X = (int)(cosTheta * (pointToRotate.X-centerPoint.X) - sinTheta * (pointToRotate.Y-centerPoint.Y) + centerPoint.X);
pt.Y = (int)(sinTheta * (pointToRotate.X - centerPoint.X) + cosTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.Y);
//p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy
return pt;
}
}
公共类IconController:控制器
{
//
//获取:/Icon/
公共行动结果索引()
{
返回视图();
}
////图标/图标?已连接=正确,标题=320,类型=logo45
公共操作结果图标(布尔连接、浮点标题、字符串类型)
{
var dir=Server.MapPath(“/images”);
//我想把红色的方块放在蓝色的长方形上。
var path=path.Combine(dir,“mapicons/center.png”);
//绿色矩形,固定黄色(实际中心)和蓝色(我真的想找到的点)
var path2=Path.Combine(dir,“mapicons/connected marker.png”);
Image innerIcon=Image.FromFile(路径);
图像标记=Image.FromFile(路径2);
使用(标记)
{
点orginalCenter=新点((marker.Width/2),(marker.Height/2));
位图markerbitmap=旋转图像(新位图(标记),标题);
marker=(图像)markerbitmap;
使用(var位图=新位图(marker.Width、marker.Height))
{
使用(var canvas=Graphics.FromImage(位图))
{
PointF newCenter=RotatePoint(原始中心,80,120,标题,标记。宽度,标记。高度);
画布.DrawRectangle(新笔(颜色.黑色),0,0,位图.宽度,位图.高度);
canvas.InterpolationMode=InterpolationMode.HighQualityBicubic;
DrawImage(标记,新矩形(0,0,标记.宽度,标记.高度),新矩形(0,0,标记.宽度,标记.高度),GraphicsUnit.Pixel);
DrawImage(innerIcon,newCenter.X-(innerIcon.Width/2),newCenter.Y-(innerIcon.Height/2));
canvas.Save();
}
尝试
{
保存(Path.Combine(dir,“result.png”)、ImageFormat.png);
path=path.Combine(dir,“result.png”);
}
捕获(例外情况除外){}
}
}
返回base.File(路径“image/png”);
}
公共静态位图旋转图像(位图b,浮动角度)
{
//原始位图需要绘制到新位图上,新位图可能会更大
//因为原始矩形的角将移动到原始矩形之外。
//一种简单的方法(可以略带“蛮力”)是计算新的边界框,即计算
//旋转后的角点,并获得最大和最小x和y坐标之间的差值。
浮子宽度2=b.宽度/2.0F;
浮动悬停2=b.高度/2.0F;
浮动弧度=-(浮动)(角度/180.0*Math.PI);
//获取角点的坐标,将原点作为位图的中心。
PointF[]角点=新的PointF[]{
新的点F(-wOver2,-hOver2),
新点F(+wOver2,-hOver2),
新的PointF(+wOver2,+hOver2),
新点F(-wOver2,+hOver2)
};
对于(int i=0;i<4;i++)
{
点f p=角点[i];
PointF newP=新的PointF((浮点)(p.X*Math.Cos(弧度)-p.Y*Math.Sin(弧度)),(浮点)(p.X*Math.Sin(弧度)+p.Y*Math.Cos(弧度));
角[i]=newP;
}
//找到最小和最大x和y坐标。
float minX=角点[0].X;
浮点最大值=最小值;
float minY=角[0].Y;
浮动最大值=最小值;
对于(int i=1;i<4;i++)
{
点f p=角点[i];
minX=Math.Min(minX,p.X);
maxX=数学最大值(maxX,p.X);
minY=Math.Min(minY,p.Y);
maxY=Math.Max(maxY,p.Y);
}
//获取新位图的大小。
SizeF newSize=newsizef(maxX-minX,maxY-minY);
//…并创造它。
位图返回位图=新位图((int)数学天花板(newSize.Width),(int)数学天花板(newSize.Height));
//现在在其上绘制旧位图。
使用(Graphics g=Graphics.FromImage(返回位图))
{
g、 TranslateTransform(newSize.Width/2.0f,newSize.Height/2.0f);
g、 旋转变换(角度);
g、 平移变换(-b.宽度/2.0f,-b.高度/2.0f);
g、 绘图图像(b,0,0);
}
返回位图;
}
公共静态点旋转点(点旋转、点中心点、双角度坐标)
{
双角度半径=角度指数*(Math.PI/180);
双cosTheta=数学Cos(角半径);
double sinTheta=数学Sin(角半径);
点pt=新点();
pt.X=(int)(cosTheta*(pointToRotate.X-centerPoint.X)-sinTheta*(pointToRotate.Y-centerPoint.Y)+centerPoint.X);
pt.Y=(int)(sinTheta*(pointToRotate.X-centerPoint.X)+cosTheta*(pointToRotate.Y-centerPoint.Y)+centerPoint.Y);
//p'y=sin(θ)*(px-ox)+cos(θ)*(py-oy)+oy
返回pt;
}
}
所以现在我需要能够在Rot中取消对TranslateTransform的注释
public ActionResult Index()
{
return View();
}
////Icon/Icon?connected=true&heading=320&type=logo45
public ActionResult Icon(bool connected, float heading, string type)
{
var dir = Server.MapPath("/images");
//RED SQUARE IM TRYING TO PLACE ON THE BLUE RECTANGLE.
var path = Path.Combine(dir, "mapicons/center.png");
//GREEN RECTANGLE WITH FIXED YELLOW (Actual center) AND BLUE (point im really trying to find)
var path2 = Path.Combine(dir, "mapicons/connected-marker.png");
Image innerIcon = Image.FromFile(path);
Image marker = Image.FromFile(path2);
using (marker)
{
Point orginalCenter = new Point((marker.Width / 2), (marker.Height / 2));
Bitmap markerbitmap = RotateImage(new Bitmap(marker), heading);
marker = (Image)markerbitmap;
using (var bitmap = new Bitmap(marker.Width, marker.Height))
{
using (var canvas = Graphics.FromImage(bitmap))
{
PointF newCenter = RotatePoint(orginalCenter, 80, 120, heading, marker.Width, marker.Height);
canvas.DrawRectangle(new Pen(Color.Black), 0, 0, bitmap.Width, bitmap.Height);
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.DrawImage(marker, new Rectangle(0, 0, marker.Width, marker.Height), new Rectangle(0, 0, marker.Width, marker.Height), GraphicsUnit.Pixel);
canvas.DrawImage(innerIcon, newCenter.X - (innerIcon.Width / 2), newCenter.Y - (innerIcon.Height / 2));
canvas.Save();
}
try
{
bitmap.Save(Path.Combine(dir, "result.png"), ImageFormat.Png);
path = Path.Combine(dir, "result.png");
}
catch (Exception ex) { }
}
}
return base.File(path, "image/png");
}
public static Bitmap RotateImage(Bitmap b, float Angle)
{
// The original bitmap needs to be drawn onto a new bitmap which will probably be bigger
// because the corners of the original will move outside the original rectangle.
// An easy way (OK slightly 'brute force') is to calculate the new bounding box is to calculate the positions of the
// corners after rotation and get the difference between the maximum and minimum x and y coordinates.
float wOver2 = b.Width / 2.0F;
float hOver2 = b.Height / 2.0F;
float radians = -(float)(Angle / 180.0 * Math.PI);
// Get the coordinates of the corners, taking the origin to be the centre of the bitmap.
PointF[] corners = new PointF[]{
new PointF(-wOver2, -hOver2),
new PointF(+wOver2, -hOver2),
new PointF(+wOver2, +hOver2),
new PointF(-wOver2, +hOver2)
};
for (int i = 0; i < 4; i++)
{
PointF p = corners[i];
PointF newP = new PointF((float)(p.X * Math.Cos(radians) - p.Y * Math.Sin(radians)), (float)(p.X * Math.Sin(radians) + p.Y * Math.Cos(radians)));
corners[i] = newP;
}
// Find the min and max x and y coordinates.
float minX = corners[0].X;
float maxX = minX;
float minY = corners[0].Y;
float maxY = minY;
for (int i = 1; i < 4; i++)
{
PointF p = corners[i];
minX = Math.Min(minX, p.X);
maxX = Math.Max(maxX, p.X);
minY = Math.Min(minY, p.Y);
maxY = Math.Max(maxY, p.Y);
}
// Get the size of the new bitmap.
SizeF newSize = new SizeF(maxX - minX, maxY - minY);
// ...and create it.
Bitmap returnBitmap = new Bitmap((int)Math.Ceiling(newSize.Width), (int)Math.Ceiling(newSize.Height));
// Now draw the old bitmap on it.
using (Graphics g = Graphics.FromImage(returnBitmap))
{
g.TranslateTransform(newSize.Width / 2.0f, newSize.Height / 2.0f);
g.RotateTransform(Angle);
g.TranslateTransform(-b.Width / 2.0f, -b.Height / 2.0f);
g.DrawImage(b, 0, 0);
}
return returnBitmap;
}
public static Point RotatePoint(Point pointToRotate, Point centerPoint, double angleInDegrees)
{
double angleInRadians = angleInDegrees * (Math.PI / 180);
double cosTheta = Math.Cos(angleInRadians);
double sinTheta = Math.Sin(angleInRadians);
Point pt = new Point();
pt.X = (int)(cosTheta * (pointToRotate.X-centerPoint.X) - sinTheta * (pointToRotate.Y-centerPoint.Y) + centerPoint.X);
pt.Y = (int)(sinTheta * (pointToRotate.X - centerPoint.X) + cosTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.Y);
//p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy
return pt;
}
}