前回は画像を矩形のなかで回転させました。このとき上下または左右に空白ができてしまいました。今回は4つの頂点が内接している状態で回転させます。この場合、画像は長方形ではなくなります。
まず原点を中心にして画像を回転させたときのことを考えます。そのとき頂点のなかにはx座標とy座標がマイナスになるものがでてくるので、平行移動させて2点が矩形の辺のうえにある状態にします。そのあと矩形にあわせて拡大・縮小すれば矩形に内接した状態で回転させることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
public partial class Form1 : Form { private void button1_Click(object sender, EventArgs e) { Bitmap srcBitmap = new Bitmap(@"D:\neko.jpg"); int r = (int)numericUpDown1.Value; Rectangle rect = new Rectangle(new Point(0, 0), new Size(pictureBox2.Width, pictureBox2.Height)); if(checkBox1.Checked) { Bitmap newBitmap =GetInscribedRotateImage(srcBitmap, rect, r); pictureBox2.Image = newBitmap; } else { Bitmap newBitmap = GetRotateImage(srcBitmap, rect, r); pictureBox2.Image = newBitmap; } } Bitmap GetInscribedRotateImage(Bitmap srcBitmap, Rectangle rect, int Rotate) { Bitmap newBitmap = new Bitmap(rect.Width, rect.Height); var srcRect = new RectangleF(-0.5f, -0.5f, srcBitmap.Width, srcBitmap.Height); // 描画元のビットマップの座標 var points = new PointF[] { new PointF(srcRect.Left, srcRect.Top), new PointF(srcRect.Right, srcRect.Top), new PointF(srcRect.Left, srcRect.Bottom), }; var points1 = new PointF[] { new PointF(srcRect.Left, srcRect.Top), new PointF(srcRect.Right, srcRect.Top), new PointF(srcRect.Left, srcRect.Bottom), new PointF(srcRect.Right, srcRect.Bottom), }; // 回転 System.Drawing.Drawing2D.Matrix matAffine1 = new System.Drawing.Drawing2D.Matrix(); matAffine1.Rotate(Rotate, System.Drawing.Drawing2D.MatrixOrder.Append); matAffine1.TransformPoints(points); matAffine1.TransformPoints(points1); float minX1 = points1.Min(x => x.X); float minY1 = points1.Min(x => x.Y); float offsetX1 = minX1 < 0 ? -minX1 : 0; float offsetY1 = minY1 < 0 ? -minY1 : 0; // 回転の中心座標まで移動させる System.Drawing.Drawing2D.Matrix matAffine2 = new System.Drawing.Drawing2D.Matrix(); matAffine2.Translate(offsetX1, offsetY1, System.Drawing.Drawing2D.MatrixOrder.Append); matAffine2.TransformPoints(points); matAffine2.TransformPoints(points1); float maxX1 = points1.Max(x => x.X); float maxY1 = points1.Max(x => x.Y); float scaleWidth = rect.Width / maxX1; float scaleHeight = rect.Height / maxY1; // 拡大・縮小 System.Drawing.Drawing2D.Matrix matAffine3 = new System.Drawing.Drawing2D.Matrix(); matAffine3.Scale(scaleWidth, scaleHeight, System.Drawing.Drawing2D.MatrixOrder.Append); matAffine3.TransformPoints(points); matAffine3.TransformPoints(points1); // 描画 using(var g = Graphics.FromImage(newBitmap)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; g.DrawImage(srcBitmap, points, srcRect, GraphicsUnit.Pixel); } return newBitmap; } } |