■ サンプル
* 以下のサンプルを載せる 【1】PictureBoxの画像内をクリックした点に、画像を配置 【2】 【1】の発展版・2点間を指定し距離を描画 【おまけ】黒い画像内画像を描画し、PictureBox内に表示する
【1】PictureBoxの画像内をクリックした点に、画像を配置
* ボタン押下で、クリアされるコード
using SampleForm.Properties; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace SampleForm { public partial class Form1 : Form { private Image sourceImage; private List<Point> targetPoints = new List<Point>(); public Form1() { InitializeComponent(); this.sourceImage = this.pictureBox1.Image; } private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) { return; } var pictureBox = sender as PictureBox; var image = Resources.Mark; var targetPoint = new Point(e.X - (image.Width / 2), e.Y - (image.Height / 2)); this.targetPoints.Add(targetPoint); this.PaintImageOnPictureBox(pictureBox, image, targetPoint); } private void pictureBox1_Paint(object sender, PaintEventArgs e) { var pictureBox = sender as PictureBox; foreach (var targetPoint in this.targetPoints) { this.PaintImageOnPictureBox(pictureBox, Resources.Mark, targetPoint); } } private void PaintImageOnPictureBox(PictureBox pictureBox, Bitmap image, Point point) { using (var graphics = pictureBox.CreateGraphics()) { graphics.DrawImage(image, point); } } // クリア処理 private void button1_Click(object sender, System.EventArgs e) { this.targetPoints.Clear(); this.pictureBox1.Image = this.sourceImage; } } }
【2】 【1】の発展版・2点間を指定し距離を描画
コードusing SampleForm.Properties; using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace SampleForm { public partial class Form1 : Form { private readonly Pen LinePen = new Pen(Color.AliceBlue, 3); private readonly Font LengthFont = new Font("メイリオ", 10); private Image sourceImage; private List<Point> targetPoints = new List<Point>(); public Form1() { InitializeComponent(); this.sourceImage = this.pictureBox1.Image; } private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) { return; } if (this.targetPoints.Count >= 2) { this.Clear(); return; } else { var pictureBox = sender as PictureBox; var image = Resources.Mark; var targetPoint = new Point(e.X, e.Y); this.targetPoints.Add(targetPoint); if (this.targetPoints.Count == 1) { this.PaintImageOnPictureBoxForMouseDown(pictureBox, image, targetPoint); return; } else if (this.targetPoints.Count == 2) { this.PaintImageOnPictureBoxForMouseDown(pictureBox, image, this.targetPoints[0], targetPoint); return; } } } private void pictureBox1_Paint(object sender, PaintEventArgs e) { var pictureBox = sender as PictureBox; if (this.targetPoints.Count == 1) { var image = Resources.Mark; this.PaintImageOnPictureBoxForPaint(pictureBox, image, this.targetPoints[0]); return; } else if (this.targetPoints.Count == 2) { var image = Resources.Mark; this.PaintImageOnPictureBoxForPaint(pictureBox, image, this.targetPoints[0], this.targetPoints[1]); return; } } private void PaintImageOnPictureBoxForMouseDown(PictureBox pictureBox, Bitmap image, Point startPoint, Point? endPoint = null) { using (var graphics = pictureBox.CreateGraphics()) { if (endPoint == null) { // 開始点 graphics.DrawImage(image, startPoint.X - (image.Width / 2), startPoint.Y - (image.Height / 2)); } else { var endPointValue = endPoint.Value; // 終了点 graphics.DrawImage(image, endPointValue.X - (image.Width / 2), endPointValue.Y - (image.Height / 2)); // 開始点と終了点との間の線 graphics.DrawLine(LinePen, startPoint, endPointValue); // 開始点と終了点との間の距離 var length = this.GetLength(startPoint, endPointValue); var lengthPointToDraw = this.CalculatePointToDraw( graphics, LengthFont, length, startPoint, endPointValue); graphics.DrawString(length, LengthFont, Brushes.Blue, lengthPointToDraw); } } } private void PaintImageOnPictureBoxForPaint(PictureBox pictureBox, Bitmap image, Point startPoint, Point? endPoint = null) { using (var graphics = pictureBox.CreateGraphics()) { // 開始点 graphics.DrawImage(image, startPoint.X - (image.Width / 2), startPoint.Y - (image.Height / 2)); if (endPoint != null) { var endPointValue = endPoint.Value; // 終了点 graphics.DrawImage(image, endPointValue.X - (image.Width / 2), endPointValue.Y - (image.Height / 2)); // 開始点と終了点との間の線 graphics.DrawLine(LinePen, startPoint, endPointValue); // 開始点と終了点との間の距離 var length = this.GetLength(startPoint, endPointValue); var lengthPointToDraw = this.CalculatePointToDraw( graphics, LengthFont, length, startPoint, endPointValue); graphics.DrawString(length, LengthFont, Brushes.Blue, lengthPointToDraw); } } } /// <summary> /// 文字列描画のための座標の計算 /// </summary> /// <param name="graphics">Graphicsオブジェクト</param> /// <param name="text">文字列</param> /// <param name="start">開始点</param> /// <param name="end">終了点</param> /// <returns>文字列描画のための座標</returns> /// <remarks>文字列を描画したときの大きさを計測する</remarks> /// <see cref="">https://dobon.net/vb/dotnet/graphics/measurestring.html"/> private Point CalculatePointToDraw(Graphics graphics, Font font, String text, Point start, Point end) { var middlePoint = this.CalculateMiddlePoint(start, end); var slope = this.CalculateSlope(start, end); if (slope >= 0) { const int Offset = 2; var textSize = graphics.MeasureString(text, font); return new Point((int)(middlePoint.X + Offset), (int)(middlePoint.Y - textSize.Height)); } else { const int Offset = 2; return new Point(middlePoint.X + Offset, middlePoint.Y + Offset); } } /// <summary> /// 2点か間の傾き計算 /// </summary> /// <param name="start">開始点</param> /// <param name="end">終了点</param> /// <returns>2点間の傾き</returns> private double CalculateSlope(Point start, Point end) { var xDiff = (double)end.X - start.X; if (xDiff == 0) { return 0; } return (end.Y - start.Y) / xDiff; } /// <summary> /// 2点か間の中点計算 /// </summary> /// <param name="start">開始点</param> /// <param name="end">終了点</param> /// <returns>2点間の中点</returns> private Point CalculateMiddlePoint(Point start, Point end) { return new Point((end.X + start.X) / 2, (end.Y + start.Y) / 2); } /// <summary> /// 2点か間の距離計算 /// </summary> /// <param name="start">開始点</param> /// <param name="end">終了点</param> /// <returns>2点間の距離</returns> private double CalculateLength(Point start, Point end) { return Math.Sqrt(Math.Pow(end.X - start.X, 2) + Math.Pow(end.Y - start.Y, 2)); } /// <summary> /// 2点か間の距離 /// </summary> /// <param name="start">開始点</param> /// <param name="end">終了点</param> /// <returns> /// 2点間の距離 (小数点第一位で出力。小数点第二位から四捨五入。 /// ex1:123456.14 => 123456.1, ex2::123456.15 => 123456.2) /// </returns> private String GetLength(Point start, Point end) { var length = this.CalculateLength(start, end); return string.Format("{0:f1}", length); } // クリア処理 private void button1_Click(object sender, System.EventArgs e) { this.Clear(); } private void Clear() { this.targetPoints.Clear(); this.pictureBox1.Image = this.sourceImage; } } }
【おまけ】黒い画像内画像を描画し、PictureBox内に表示する
using SampleForm.Properties; using System; using System.Drawing; using System.Windows.Forms; namespace SampleForm { public partial class Form4 : Form { public Form4() { InitializeComponent(); } private void Form4_Load(object sender, EventArgs e) { var canvas = new Bitmap(400, 400); using (var graphics = Graphics.FromImage(canvas)) { // 全体を黒で塗りつぶす graphics.FillRectangle(Brushes.Black, graphics.VisibleClipBounds); // その中に画像を突っ込む var innerImage = Resources._1; graphics.DrawImage(innerImage, new Point(100, 130)); } // 作成した画像を表示する this.pictureBox1.Image = canvas; } } }
参考文献
DrawImage() についてhttps://imagingsolution.net/program/csharp/drawimage/
https://dobon.net/vb/dotnet/graphics/drawimage.html
http://www.wisdomsoft.jp/514.html
【おまけ】黒い画像内画像を描画し、PictureBox内に表示する
https://dobon.net/vb/dotnet/graphics/createimage.html
関連記事
Windows Form ~ 目次 ~
https://blogs.yahoo.co.jp/dk521123/8054245.htmlGraphics ~ さまざまな描画 ~
https://blogs.yahoo.co.jp/dk521123/32877749.htmlPictureBox
PictureBox [1] ~ 画像を表示する ~https://blogs.yahoo.co.jp/dk521123/23504075.html
PictureBox [2] ~ PictureBox を マウスで移動する ~
https://blogs.yahoo.co.jp/dk521123/37861699.html
PictureBox [3] ~ マウスホイール で画像の拡大・縮小する ~
https://blogs.yahoo.co.jp/dk521123/37866101.html
PictureBox [4] ~ PictureBox 内に文字列を描画する ~
https://blogs.yahoo.co.jp/dk521123/37890831.html