C# 如何旋转图像,然后移动到左上角0,0,而不切断图像
如何旋转图像,然后移动到左上角0,0,而不切断图像 请阅读代码中的注释。我在第三步被卡住了 我认为用三角学应该能解决这个问题 谢谢C# 如何旋转图像,然后移动到左上角0,0,而不切断图像,c#,gdi+,C#,Gdi+,如何旋转图像,然后移动到左上角0,0,而不切断图像 请阅读代码中的注释。我在第三步被卡住了 我认为用三角学应该能解决这个问题 谢谢 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
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);
//STEP 1 move rotation point to top left
g.TranslateTransform((float)0, (float)0);
//STEP 2 rotate
g.RotateTransform(angle);
//STEP 3 move image back to top left without cutting off the image
//SOME trigonometry calculation here
int newY = b.Height;
g.TranslateTransform(-(float)0, -newY);
//draw passed in image onto graphics object
g.DrawImage(b, new Point(0, 0));
return returnBitmap;
}
这包括“三角学”吗?我已经做了第0步,因为我认为你需要先做。通过这种方式,您可以计算得到的位图的大小,它会更大-请参阅代码中的注释
private 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;
}
私有位图旋转图像(位图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);
}
返回位图;
}
这包括“三角学”吗?我已经做了第0步,因为我认为你需要先做。通过这种方式,您可以计算得到的位图的大小,它会更大-请参阅代码中的注释
private 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;
}
私有位图旋转图像(位图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);
}
返回位图;
}
TranslateTransform(0,0)
不会做你认为它会做的事情。您需要TranslateTransform(b.Width/2,b.Height/2)
。这将使图像的中心位于原点。然而,剩下的我就不懂了。我想把所有的东西移到0,0坐标会使正弦,余弦,切线的事情变得容易得多。我的示例不需要移动到0,0,因为已经位于0,0TranslateTransform(0,0)
的图像不符合您的想法。您需要TranslateTransform(b.Width/2,b.Height/2)
。这将使图像的中心位于原点。然而,剩下的我就不懂了。我想把所有的东西移到0,0坐标会使正弦,co更容易