作成した画像を左右反転させたものを作りたいときがあります。そこで左右や上下を反転させたり回転させることができるようにします。また反転・回転の対象も全体、選択されている部分だけに限定するというように両方に対応させます。
まず全体を対象にする場合、範囲選択されていたら解除することにしました。そのあと反転・回転の処理をおこないます。このときにBitmap.RotateFlipメソッドを使います。
bitmap.RotateFlip(RotateNoneFlipX) // 左右反転
bitmap.RotateFlip(RotateNoneFlipY) // 上下反転
bitmap.RotateFlip(Rotate90FlipNone) // 90度回転
bitmap.RotateFlip(Rotate180FlipNone) // 180度回転
bitmap.RotateFlip(Rotate270FlipNone) // 270度回転
まずはパネルの色をつかってBitmapをつくります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public partial class Form1 : Form { Bitmap GetBitmapFromPanels(Rectangle rect) { ClearSelectionForSaveUndobuf(); Bitmap bitmap = new Bitmap(rect.Width, rect.Height); for(int i = rect.X; i < rect.X+ rect.Width; i++) { for(int j = rect.Y; j < rect.Y + rect.Height; j++) { bitmap.SetPixel(i- rect.X, j- rect.Y, panels[i, j].BackColor); } } RestoreSelectionAfterSaveUndobuf(); return bitmap; } } |
Bitmapからパネルを復元するメソッドもつくります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public partial class Form1 : Form { void RestorePanelsFromBitmap(Bitmap bitmap) { ClearSelectionForSaveUndobuf(); for(int i = 0; i < 32; i++) { for(int j = 0; j < 32; j++) { panels[j, i].BackColor = bitmap.GetPixel(j, i); } } RestoreSelectionAfterSaveUndobuf(); } } |
反転・回転は以下のメソッドでおこないます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public partial class Form1 : Form { void RotateFlip(RotateFlipType rotateFlipType) { ClearSelectionXYs(); // 範囲選択されていたら解除 SaveOldBitmap(); Bitmap allBitmap = GetBitmapFromPanels(); allBitmap.RotateFlip(rotateFlipType); RestorePanelsFromBitmap(allBitmap); allBitmap.Dispose(); InsertUndobuf(); } } |
あとは
RotateFlip(RotateFlipType.RotateNoneFlipX);
とやれば左右反転ができるし、
RotateFlip(RotateFlipType.Rotate90FlipNone);
とやれば90度回転もできます。
次に範囲選択されているときに選択範囲内での反転・回転を考えます。
まず選択されている位置を求めます。以下のメソッドは選択されている部分の矩形を返します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public partial class Form1 : Form { Rectangle GetSelectRectangle() { if(SelectionXYs.Count == 0) return new Rectangle(0, 0, 0, 0); int pointX = SelectionXYs.Min(x => x.X); int pointY = SelectionXYs.Min(x => x.Y); int maxX = SelectionXYs.Max(x => x.X); int maxY = SelectionXYs.Max(x => x.Y); int width = maxX - pointX + 1; int height = maxY - pointY + 1; return new Rectangle(pointX, pointY, width, height); } } |
そして以下のメソッドで反転と回転の処理をおこないます。範囲選択されている場合、元の色に戻せるように元の色を保存しているのですが、これだと枠の部分が反転処理できないので、いったんSelectionXYsをクリアしています。
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 |
public partial class Form1 : Form { void SelectionRotateFlip(RotateFlipType rotateFlipType) { SaveOldBitmap(); Bitmap allBitmap = GetBitmapFromPanels(); Rectangle SelectRectangle = GetSelectRectangle(); Bitmap selectBitmap = GetBitmapFromPanels(SelectRectangle); selectBitmap.RotateFlip(rotateFlipType); Graphics g = Graphics.FromImage(allBitmap); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; g.DrawImage(selectBitmap, SelectRectangle); g.Dispose(); var list = SelectionXYs.ToList(); // SelectionXYsをクリアするまえにバックアップする SelectionXYs.Clear(); RestorePanelsFromBitmap(allBitmap); selectBitmap.Dispose(); allBitmap.Dispose(); foreach(var xy in list) { xy.oldColor = panels[xy.X, xy.Y].BackColor; panels[xy.X, xy.Y].BackColor = Color.Tan; } SelectionXYs = list; InsertUndobuf(); } } |
あとは
SelectionRotateFlip(RotateFlipType.RotateNoneFlipX); // 選択部分だけ左右反転させる
SelectionRotateFlip(RotateFlipType.Rotate90FlipNone); // 選択部分だけ90度回転させる
とやれば処理ができます。