这样做有一些懒散和饥饿的算法,但到目前为止我还没有提出或发现任何特别快的算法。
答案 0 :(得分:5)
最快的方法是使用不安全的调用直接使用LockBits
操作图像内存。这听起来很吓人但是很直接。如果你搜索LockBits,你会发现很多例子,例如here。
有趣的是:
BitmapData originalData = originalBitmap.LockBits(
new Rectangle(0, 0, originalWidth, originalHeight),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppRgb);
获得BitmapData后,您可以传递像素并将它们映射到新图像(再次使用LockBits)。这比使用Graphics
API快得多。
答案 1 :(得分:4)
这是我最终做的事情(经过大量的持续研究,以及TheCodeKing提供的有用链接):
public Image RotateImage(Image img, float rotationAngle)
{
// When drawing the returned image to a form, modify your points by
// (-(img.Width / 2) - 1, -(img.Height / 2) - 1) to draw for actual co-ordinates.
//create an empty Bitmap image
Bitmap bmp = new Bitmap((img.Width * 2), (img.Height *2));
//turn the Bitmap into a Graphics object
Graphics gfx = Graphics.FromImage(bmp);
//set the point system origin to the center of our image
gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
//now rotate the image
gfx.RotateTransform(rotationAngle);
//move the point system origin back to 0,0
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;
//draw our new image onto the graphics object with its center on the center of rotation
gfx.DrawImage(img, new PointF((img.Width / 2), (img.Height / 2)));
//dispose of our Graphics object
gfx.Dispose();
//return the image
return bmp;
}
干杯!
答案 2 :(得分:0)
void Graphics.RotateTransform(float angle);
这应该在C#中旋转图像。这是做什么的呢?
我没有用GDI +进行太多实验。记住在绘制图像后反转旋转。
答案 3 :(得分:0)
此答案返回应该绘制的偏移量和已旋转的图像。它的工作原理是将新图像重新创建为应该没有剪切角度的大小。最初由Hisenburg在#C#IRC聊天室和Bloodyaugust撰写。
public static double NormalizeAngle(double angle)
{
double division = angle / (Math.PI / 2);
double fraction = Math.Ceiling(division) - division;
return (fraction * Math.PI / 2);
}
public static Tuple<Image,Size> RotateImage(Image img, double rotationAngle)
{
double normalizedRotationAngle = NormalizeAngle(rotationAngle);
double widthD = img.Width, heightD = img.Height;
double newWidthD, newHeightD;
newWidthD = Math.Cos(normalizedRotationAngle) * widthD + Math.Sin(normalizedRotationAngle) * heightD;
newHeightD = Math.Cos(normalizedRotationAngle) * heightD + Math.Sin(normalizedRotationAngle) * widthD;
int newWidth, newHeight;
newWidth = (int)Math.Ceiling(newWidthD);
newHeight = (int)Math.Ceiling(newHeightD);
Size offset = new Size((newWidth - img.Width) / 2,(newHeight - img.Height) / 2);
Bitmap bmp = new Bitmap(newWidth, newHeight);
Graphics gfx = Graphics.FromImage(bmp);
//gfx.Clear(Color.Blue);
gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
gfx.RotateTransform((float)(rotationAngle / Math.PI * 180));
gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.DrawImage(img, new PointF((bmp.Width / 2 - img.Width / 2), (bmp.Height / 2 - img.Height / 2)));
gfx.Dispose();
return new Tuple<Image,Size>(bmp,offset);
}