ペイントソフトなどにある「ひとつ前に戻る機能」がどの様なものか考え試作してみました。
namespace FreeHand2;
public class ImgObject : IDisposable
{
public Bitmap Bitmap {get; set;} = new Bitmap(1,1);
public Rectangle Rectangle {get; set;} = new Rectangle(0,0,1,1);
public void Dispose()
{
Bitmap?.Dispose();
}
}
public class MyCanvas : UserControl
{
// コンストラクタ
public MyCanvas()
{
AutoScroll = true;// 自動スクロール
bool isDrawing = false;
Point lastMousePoint = new Point(-1, -1); // 前回マウスボタンを押した位置
List<ImgObject> imgObjects = new(); // 画像オブジェクト
// マウスボタン押すイベント
_pictureBox.MouseDown += (s, e) =>
{
if (s == null) return;
PictureBox o = (PictureBox)s;
switch(e.Button)
{
case MouseButtons.Right:
// 右ボタン
int pos = imgObjects.Count - 1;
if (pos < 0) return;
imgObjects.RemoveAt(pos);
_pictureBox.Invalidate();
break;
case MouseButtons.Left:
// 左ボタン
isDrawing = true;
lastMousePoint = e.Location;
Bitmap bmp = new(o.Image.Width, o.Image.Height);
using(var g = Graphics.FromImage(bmp))
{
g.Clear(Color.FromArgb(0,255,255,255));
}
ImgObject io = new()
{
Bitmap = bmp,
Rectangle = new Rectangle(0, 0, bmp.Width, bmp.Height),
};
imgObjects.Add(io);
break;
}
};
// マウスボタン離すイベント
_pictureBox.MouseUp += (s, e) =>
{
switch(e.Button)
{
case MouseButtons.Right:
// 右ボタン
break;
case MouseButtons.Left:
// 左ボタン
isDrawing = false;
break;
}
};
// マウス移動イベント
_pictureBox.MouseMove += (s, e) =>
{
if (isDrawing == false) return;
int pos = imgObjects.Count - 1;
if (pos < 0) return;
using(var g = Graphics.FromImage(imgObjects[pos].Bitmap))
{
g.DrawLine(Pens.Black, lastMousePoint, e.Location);
}
lastMousePoint = e.Location;
_pictureBox.Invalidate();
};
// ペイントイベント
_pictureBox.Paint += (s, e) =>
{
var g = e.Graphics;
g.Clear(Color.White);
foreach(var io in imgObjects)
{
g.DrawImage(io.Bitmap, io.Rectangle);
}
};
Controls.Add(_pictureBox);
}
PictureBox _pictureBox = new()
{
Image = new Bitmap(800, 600),
SizeMode = PictureBoxSizeMode.AutoSize,
};
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MyCanvas myCanvas = new()
{
Dock = DockStyle.Fill,
};
Controls.Add(myCanvas);
}
}
マウスの右ボタンを押したまま移動すると線が引かれます。左ボタンを押すとひとつ前に戻ります。
プログラムの内容は1ストローク事透明な画像を用意し、そちらに線を描画しています。描画した画像をを配列にし、ピクチャボックスのペイントイベントで配列の要素をDrawImageで重ね合わせ処理をしています。相対位置やサイズを想定してRectangleプロパティ用意しましたが、今回は無用でした。
実際、ペイントソフトでどのような処理をしているかは不明ですが、描画の手順が配列化されていますので、直近追加した要素を削除すると、一つ前に戻る(undo)機能になります。
C#でフリーハンドで線を引く
線を引く機能とマウスの移動イベントを組み合わせると、ペイントソフトのフリーハンドで線を引く機能のようなものが作れるので試してみました。事前準備線を引くサンプルソースファイル名:drawline.csusing System;using Sy...
コメント