矩形、楕円を描画する
まずメニューを作成します。そして以下のような列挙体を作成します。
1 2 3 4 5 6 7 8 |
public enum EditMode { Selection, // 通常の範囲指定 DrawRectangle, // 枠だけの長方形を描く FillRectangle, // 塗りつぶしの長方形を描く DrawEllipse, // 枠だけの楕円を描く FillEllipse, // 塗りつぶしの楕円を描く } |
1 2 3 4 5 6 7 8 9 |
public partial class UserControlImage : UserControl { public EditMode EditMode { set; get; } = EditMode.Selection; } |
メニューで各項目が指定されている場合はメニューにチェックマークがつきます。
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 |
public partial class Form1 : Form { void CheckMenu1(ToolStripMenuItem menuItem) { SelectionMenuItem.Checked = false; DrawFigureMenuItem.Checked = false; DrawRectangleMenuItem.Checked = false; FillRectangleMenuItem.Checked = false; DrawEllipseMenuItem.Checked = false; FillEllipseMenuItem.Checked = false; if(menuItem == SelectionMenuItem) SelectionMenuItem.Checked = true; else if(menuItem == DrawRectangleMenuItem) { DrawFigureMenuItem.Checked = true; DrawRectangleMenuItem.Checked = true; } else if(menuItem == FillRectangleMenuItem) { DrawFigureMenuItem.Checked = true; FillRectangleMenuItem.Checked = true; } else if(menuItem == DrawEllipseMenuItem) { DrawFigureMenuItem.Checked = true; DrawEllipseMenuItem.Checked = true; } else if(menuItem == FillEllipseMenuItem) { DrawFigureMenuItem.Checked = true; FillEllipseMenuItem.Checked = true; } } private void SelectionMenuItem_Click(object sender, EventArgs e) { CheckMenu1(SelectionMenuItem); userControlImage1.EditMode = EditMode.Selection; } private void DrawRectangleMenuItem_Click(object sender, EventArgs e) { CheckMenu1(DrawRectangleMenuItem); userControlImage1.EditMode = EditMode.DrawRectangle; } private void FillRectangleMenuItem_Click(object sender, EventArgs e) { CheckMenu1(FillRectangleMenuItem); userControlImage1.EditMode = EditMode.FillRectangle; } private void DrawEllipseMenuItem_Click(object sender, EventArgs e) { CheckMenu1(DrawEllipseMenuItem); userControlImage1.EditMode = EditMode.DrawEllipse; } private void FillEllipseMenuItem_Click(object sender, EventArgs e) { CheckMenu1(FillEllipseMenuItem); userControlImage1.EditMode = EditMode.FillEllipse; } } |
ピクチャーボックスにおけるクリックとドラッグ
ユーザーコントロール UserControlImage上でドラッグがおこなわれると編集モードによって範囲指定がおこなわれたり、矩形や楕円の描画がおこなわれるような機能を追加します。
そのためにUserControlImageクラスのPictureBox1_MouseDown、PictureBox1_MouseMove、PictureBox1_MouseUpを修正します。
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 |
public partial class UserControlImage : UserControl { private void PictureBox1_MouseDown(object sender, MouseEventArgs e) { if(Bitmap == null) return; // 範囲外におけるクリック if(e.X + ScrollBarPosX >= Bitmap.Width || e.Y + ScrollBarPosY >= Bitmap.Height) { OnMouseDownOutOfBitmap(); return; } // クリックされた場所の色を通知する if(PictureBoxMouseDown != null) { Color color = Bitmap.GetPixel(e.X + ScrollBarPosX, e.Y + ScrollBarPosY); PictureBoxMouseDown(this, new PictureBox1MouseDownArgs(e.X + ScrollBarPosX, e.Y + ScrollBarPosY, color)); } if(BitmapRectangle == null) { if(EditMode == EditMode.Selection) OnMouseDownForSelectRectangle(new Point(e.X + ScrollBarPosX, e.Y + ScrollBarPosY)); // 矩形と楕円の描画 if(EditMode == EditMode.DrawRectangle || EditMode == EditMode.FillRectangle || EditMode == EditMode.DrawEllipse || EditMode == EditMode.FillEllipse) OnMouseDownForDrawRectangle(new Point(e.X + ScrollBarPosX, e.Y + ScrollBarPosY)); } else { if(IsPointInRectangle(new Point(e.X + ScrollBarPosX, e.Y + ScrollBarPosY), BitmapRectangle.Rectangle)) OnMouseDownInBitmapRectangle(new Point(e.X + ScrollBarPosX, e.Y + ScrollBarPosY)); else OnMouseDownOutOfSelection(new Point(e.X + ScrollBarPosX, e.Y + ScrollBarPosY)); } } void OnMouseDownForDrawRectangle(Point bitmapPoint) { isMouseDown = true; pictureBox1.Capture = true; startPoint = new Point(bitmapPoint.X, bitmapPoint.Y); } } |
矩形と楕円を描画するのであればどの色をつかっておこなうのかを決める必要があります。
ここで色を設定できるようにしました。
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 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); userControlImage1.PictureBoxMouseDown += UserControlImage1_PictureBoxMouseDown; userControlColorBox1.Anchor = AnchorStyles.Top | AnchorStyles.Right; userControlColorBox2.Anchor = AnchorStyles.Top | AnchorStyles.Right; userControlColorBox3.Anchor = AnchorStyles.Top | AnchorStyles.Right; pictureBoxSetColor.BackColor = userControlImage1.DrawColor; ShowInitBitmap(); } private void buttonSetColor_Click(object sender, EventArgs e) { ColorDialog dlg = new ColorDialog(); if(dlg.ShowDialog() == DialogResult.OK) { pictureBoxSetColor.BackColor = dlg.Color; userControlImage1.DrawColor = dlg.Color; } dlg.Dispose(); } } |
1 2 3 4 5 6 7 8 9 |
public partial class UserControlImage : UserControl { public Color DrawColor { set; get; } = Color.Black; } |
あとはドラッグされたときに描画してドロップされたときに確定するだけです。
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 |
public partial class UserControlImage : UserControl { private void PictureBox1_MouseMove(object sender, MouseEventArgs e) { if(Bitmap == null) return; if(isMouseDown) { if(EditMode == EditMode.Selection) OnMouseMoveForSelectRectangle(new Point(e.X + ScrollBarPosX, e.Y + ScrollBarPosY)); // 追加部分 if(EditMode == EditMode.DrawRectangle || EditMode == EditMode.FillRectangle || EditMode == EditMode.DrawEllipse || EditMode == EditMode.FillEllipse) OnMouseMoveForDrawRectangle(new Point(e.X + ScrollBarPosX, e.Y + ScrollBarPosY)); } } void OnMouseMoveForDrawRectangle(Point bitmapPoint) { endPoint = bitmapPoint; Bitmap newBitmap = DrawRectangle(GetRectangle(startPoint, endPoint)); ShowBitmap(DrawBoderRectangle(newBitmap)); newBitmap.Dispose(); } Bitmap DrawRectangle(Rectangle bitmapRect) { Bitmap newBitmap = new Bitmap(Bitmap); Graphics g = Graphics.FromImage(newBitmap); if(EditMode == EditMode.DrawRectangle) g.DrawRectangle(new Pen(DrawColor), bitmapRect); if(EditMode == EditMode.FillRectangle) g.FillRectangle(new SolidBrush(DrawColor), bitmapRect); if(EditMode == EditMode.DrawEllipse) g.DrawEllipse(new Pen(DrawColor), bitmapRect); if(EditMode == EditMode.FillEllipse) g.FillEllipse(new SolidBrush(DrawColor), bitmapRect); g.Dispose(); return newBitmap; } } |
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 |
public partial class UserControlImage : UserControl { private void PictureBox1_MouseUp(object sender, MouseEventArgs e) { if(Bitmap == null) return; if(isMouseDown) { // 矩形描画で変更 if(EditMode == EditMode.Selection) OnMouseUpForSelectRectangle(); if(EditMode == EditMode.DrawRectangle || EditMode == EditMode.FillRectangle || EditMode == EditMode.DrawEllipse || EditMode == EditMode.FillEllipse) OnMouseUpForDrawRectangle(); } } void OnMouseUpForDrawRectangle() { isMouseDown = false; Rectangle rect = GetRectangle(startPoint, endPoint); if(rect.IsEmpty || rect.Width == 0 || rect.Height == 0) return; Bitmap newBitmap = DrawRectangle(GetRectangle(startPoint, endPoint)); Bitmap rectBitmap = new Bitmap(rect.Width + 1, rect.Height + 1); Graphics g = Graphics.FromImage(rectBitmap); if(EditMode == EditMode.DrawRectangle) g.DrawRectangle(new Pen(DrawColor), new Rectangle(0,0,rect.Width, rect.Height)); if(EditMode == EditMode.FillRectangle) g.FillRectangle(new SolidBrush(DrawColor), new Rectangle(0, 0, rect.Width, rect.Height)); if(EditMode == EditMode.DrawEllipse) g.DrawEllipse(new Pen(DrawColor), new Rectangle(0, 0, rect.Width, rect.Height)); if(EditMode == EditMode.FillEllipse) g.FillEllipse(new SolidBrush(DrawColor), new Rectangle(0, 0, rect.Width, rect.Height)); g.Dispose(); BitmapRectangle = new BitmapRectangle(new Bitmap(rectBitmap), rect); Bitmap = newBitmap; ShowBitmap(DrawBoderRectangle(Bitmap)); } } |