【C#】ドラッグで短形選択し、画像を切り取って表示する
C#に触れる機会があり、マウスドラッグでの短形選択→画像切り取りで少し悩んだので覚えとして記録しておきます。
ドラッグで短形選択し、画像を切り取って表示
今回使用した環境
インターネット接続可能のオンラインの環境
64 ビット オペレーティング システム
Windows 10 21H1
Visual Studio 2022 C# .NET Framework 4.8
フォームデザイン
フォームの中にPictureBoxを2つ配置し、「pictureBox1」には切り取りを行う元の画像、「pictureBox2」には切り取り後の画像を表示することとします。
動作イメージ
マウスドラッグで短形選択することで、選択された領域を画面右側に表示します。
ソースコード
using System;
using System.Drawing;
using System.Windows.Forms;
namespace ImageCut
{
public partial class Form1 : Form
{
// ドラッグ開始位置 ( 短形選択開始点 )
private Point _startPoint;
// ドロップ位置 ( 短形選択終了点 )
private Point _endPoint;
// 切り取り前のオリジナル画像
private Image _srcImage;
// 切り取り前のオリジナル画像 ( バックアップ )
private Image _srcImageBk;
public Form1()
{
InitializeComponent();
}
// フォームロード時
private void Form1_Load(object sender, EventArgs e)
{
_srcImage = Image.FromFile("D:\\image\\bike.jpeg");
_srcImageBk = (Image)_srcImage.Clone();
pictureBox1.Image = _srcImage;
}
// マウスダウン時
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
// ドラッグ開始位置を取得
_startPoint.X = e.X;
_startPoint.Y = e.Y;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// 切り取り中の幅、高さを取得
int cuttingWidth = Math.Abs(e.X - _startPoint.X);
int cuttingHeight = Math.Abs(e.Y - _startPoint.Y);
// バックアップして置いたオリジナルのイメージで描画してから選択中の短形を描画
using (Graphics g = Graphics.FromImage(_srcImage))
{
g.DrawImage(_srcImageBk, 0, 0);
g.DrawRectangle(Pens.Black, (e.X - _startPoint.X >= 0) ? _startPoint.X : _startPoint.X - cuttingWidth,
(e.Y - _startPoint.Y >= 0) ? _startPoint.Y : _startPoint.Y - cuttingHeight,
cuttingWidth, cuttingHeight);
}
// pictureBox1に選択中の短形を表示
pictureBox1.Refresh();
}
}
// マウスアップ時
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
// pictureBox1の短形選択を消去
using (Graphics g = Graphics.FromImage(_srcImage))
{
g.DrawImage(_srcImageBk, 0, 0);
}
pictureBox1.Refresh();
// ドロップ位置を取得
_endPoint.X = e.X;
_endPoint.Y = e.Y;
// 切り取り後の幅、高さを取得
int cuttingWidth = Math.Abs(_endPoint.X - _startPoint.X);
int cuttingHeight = Math.Abs(_endPoint.Y - _startPoint.Y);
// 描画位置
Rectangle destRect = new Rectangle(0, 0, cuttingWidth, cuttingHeight);
// 切り取る短形
Rectangle srcRect = new Rectangle((_endPoint.X - _startPoint.X >= 0) ? _startPoint.X : _startPoint.X - cuttingWidth,
(_endPoint.Y - _startPoint.Y >= 0) ? _startPoint.Y : _startPoint.Y - cuttingHeight,
cuttingWidth, cuttingHeight);
// 切り取り後の幅、高さでBitmapインスタンスを生成
Bitmap cuttingImage = new Bitmap(cuttingWidth, cuttingHeight);
// 描画
using (Graphics g = Graphics.FromImage(cuttingImage))
{
g.DrawImage(_srcImage, destRect, srcRect, GraphicsUnit.Pixel);
}
// pictureBox2に切り取り後の画像を表示
pictureBox2.Image = cuttingImage;
pictureBox2.Refresh();
}
}
}
※上記ソースは左上→右下のドラッグ方向だけではなく、あらゆる方向へのドラッグに対応させた結果、申し訳ありませんが、若干ソースとして見にくくなっています。55行目や87行目の三項演算子がそれにあたります。
動作確認
短形選択した画像が切り取られ、画面右側に表示されました。
以上となります。
ここまでお読みいただきありがとうございました。