Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在旋转c后找到图像中的原点#_C#_Image_Rotation_Point - Fatal编程技术网

C# 在旋转c后找到图像中的原点#

C# 在旋转c后找到图像中的原点#,c#,image,rotation,point,C#,Image,Rotation,Point,下面的图片说明了我正在尝试做什么 我正在旋转c#(白色矩形)中的图像。 问题是,我需要将绿色正方形(另一个图像)放置在相对于矩形的同一点上,而不考虑旋转。绿色正方形不能与矩形一起旋转 正如你们所看到的,在白色矩形旋转之后,每次我都会得到不同大小的画布 我试图找到一个确切的点,以放置绿色正方形后,新的旋转图像创建 下面是一些旋转图像并将圆点放置在正确位置的代码。 现在的问题是,如果我在RotateImage方法中应用变换,我会看到所有的矩形,但很明显,我的红点在错误的位置。 我应该强调的是,我需

下面的图片说明了我正在尝试做什么

我正在旋转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;

    }
}