ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

C# 画像にラインを引く

C#でPictureBoxに表示している画像上に直線を引きたい場合についてのメモ。

f:id:moko_03_25:20200308025641g:plain

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace SampleRubberBand
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			// 画像ファイルからImageを作成
			Image img = Image.FromFile("sample.png");

			// 画像を表示
			pictureBox1.Image = img;

			// 画像をバックアップしておく
			backupImage = new Bitmap(img);
		}

		// 変数
		Point startPoint;
		Point endPoint;

		Color lineColer = Color.Red;
		int lineBorder = 4;

		Bitmap backupImage;
		Graphics g;
		Pen linePen;

		// マウスダウン時
		private void PictureBox1_MouseDown(object sender, MouseEventArgs e)
		{
			// 座標を保存
			startPoint.X = cursorPos().X;
			startPoint.Y = cursorPos().Y;
		}

		// マウスドラッグ中
		private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
		{
			// マウスの左ボタンが押されている場合のみ処理
			if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left)
			{
				// 座標を取得
				endPoint.X = cursorPos().X;
				endPoint.Y = cursorPos().Y;

				// 描画
				DrawLine(startPoint, endPoint);
			}
		}

		// マウスアップ時
		private void PictureBox1_MouseUp(object sender, MouseEventArgs e)
		{
			// リソースを解放
			linePen.Dispose();
			g.Dispose();
		}

		// カーソル位置を取得
		private Point cursorPos()
		{
			// 画面座標でカーソルの位置を取得
			Point p = Cursor.Position;
			// 画面座標からコントロール上の座標に変換
			Point cp = this.PointToClient(p);

			return cp;
		}

		// ラインを描画
		private void DrawLine(Point p0, Point p1)
		{
			// 画像のバックアップを取得
			Bitmap canvasBase = new Bitmap(pictureBox1.Image);

			// 描画するImageオブジェクトを作成
			// サイズだけ指定すると無色透明のキャンバスになる
			Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
			//ImageオブジェクトのGraphicsオブジェクトを作成する
			g = Graphics.FromImage(canvas);

			// Penオブジェクトの作成
			linePen = new Pen(lineColer, lineBorder);

			// 先にバックアップしていた画像で塗り潰す
			g.DrawImage(backupImage, 0, 0);

			// ドットスタイルを指定
			linePen.DashStyle = DashStyle.Dot;
			// ラインを描画
			g.DrawLine(linePen, p0.X, p0.Y, p1.X, p1.Y);

			// PictureBox1に表示
			pictureBox1.Image = canvas;
		}
	}
}