ペイントツールでよくある範囲選択(切り取り)機能です
前回のプログラムに付け足すような形で追加しています
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.Remoting;
using System.Windows.Forms;
namespace ImageEditing
{
public partial class frmPaintTool : Form
{
// 変数
Bitmap _newBitMap; // ビットマップ画像
Bitmap _oldBitMap; // ビットマップ画像
Bitmap _selectBitMap; // ビットマップ画像
bool _mouseDrug; // マウスクリック中のフラグ
bool _moveFirst; // 初回の画像移動のフラグ
bool _moveImage; // 画像移動中のフラグ
int _prevX; // 前のマウスカーソルのX座標
int _prevY; // 前のマウスカーソルのY座標
int _startX; // スタートのマウスカーソルのX座標
int _startY; // スタートのマウスカーソルのY座標
int _selectX; // 選択中の範囲のX座標
int _selectY; // 選択中の範囲のY座標
int _penType; // ペンモード
Rectangle _selectedRect; // 選択範囲の記憶
public frmPaintTool()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// BitMapオブジェクトを生成する
// 背景色として白で塗りつぶす
_newBitMap = new Bitmap(DrawingPicBox.Width, DrawingPicBox.Height);
Graphics objGrp = Graphics.FromImage(_newBitMap);
SolidBrush objBrush = new SolidBrush(Color.White);
objGrp.FillRectangle(objBrush, 0, 0, _newBitMap.Width, _newBitMap.Height);
objGrp.Dispose();
objBrush.Dispose();
// ビットマップ画像をコピー
_oldBitMap = (Bitmap)_newBitMap.Clone();
}
private void DrawingPicBox_MouseDown(object sender, MouseEventArgs e)
{
// マウスクリック開始判定
_mouseDrug = true;
if (_penType == 2)
{
// 選択ツールが選択されている場合
// マウスカーソルの位置を取得する
Point clickPoint = new Point(e.X, e.Y);
if (_selectedRect.Contains(clickPoint) == true)
{
// マウスカーソルが前回の選択範囲の中でクリックされたとき
if (_moveFirst == true)
{
PixelFormat format = _newBitMap.PixelFormat;
// 範囲の画像を切り取る
_selectBitMap = _newBitMap.Clone(_selectedRect, format);
}
// 移動モードに移行する
_moveImage = true;
}
else
{
// マウスカーソルが範囲の外を選択したとき
if (_moveImage == true)
{
// 画像を移動していたとき
Graphics objGrp = Graphics.FromImage(_oldBitMap);
// 変更を確定する
// DrawImage()で、選択された画像_selectBitMapを指定した位置に描画する
objGrp.DrawImage(_selectBitMap, _selectedRect);
objGrp.Dispose();
_selectBitMap.Dispose();
}
_newBitMap = (Bitmap)_oldBitMap.Clone();
_moveFirst = true;
_moveImage = false;
}
DrawingPicBox.Image = _newBitMap;
}
// マウスカーソル位置記憶の初期化
_prevX = e.Location.X;
_prevY = e.Location.Y;
_startX = e.Location.X;
_startY = e.Location.Y;
}
private void DrawingPicBox_MouseUp(object sender, MouseEventArgs e)
{
// マウスクリック終了判定
_mouseDrug = false;
if (_penType == 2)
{
// 選択ツールが選択されている場合
if (_moveImage == false)
{
// 画像範囲選択中のとき
if (_startX <= _prevX)
{
// 選択した画像範囲を_selectedRectに記憶する
if (_startY <= _prevY)
{
_selectedRect = new Rectangle(_startX, _startY, _prevX - _startX, _prevY - _startY);
_selectX = _startX; // 選択範囲のスタート位置を記憶する
_selectY = _startY;
}
else
{
_selectedRect = new Rectangle(_startX, _prevY, _prevX - _startX, _startY - _prevY);
_selectX = _startX; // 選択範囲のスタート位置を記憶する
_selectY = _prevY;
}
}
else
{
if (_startY <= _prevY)
{
_selectedRect = new Rectangle(_prevX, _startY, _startX - _prevX, _prevY - _startY);
_selectX = _prevX; // 選択範囲のスタート位置を記憶する
_selectY = _startY;
}
else
{
_selectedRect = new Rectangle(_prevX, _prevY, _startX - _prevX, _startY - _prevY);
_selectX = _prevX; // 選択範囲のスタート位置を記憶する
_selectY = _prevY;
}
}
}
else
{
// 画像移動中のとき
// 移動した後の画像範囲のスタート位置を記憶する
_selectX = _selectX + e.Location.X - _startX;
_selectY = _selectY + e.Location.Y - _startY;
// 移動した後の画像範囲を_selectedRectに記憶する
_selectedRect = new Rectangle(_selectX, _selectY, _selectBitMap.Width, _selectBitMap.Height);
}
return;
}
// 変更を保存する
_oldBitMap = (Bitmap)_newBitMap.Clone();
}
private void DrawingPicBox_MouseMove(object sender, MouseEventArgs e)
{
// マウスクリック中に、BitMapにGraphicsオブジェクトで描画する
if (_mouseDrug == true)
{
// BitMapからGraphicsオブジェクトを生成
// 選択されているツールの種類によって処理を分ける
Graphics objGrp = Graphics.FromImage(_newBitMap);
Pen objPen = null;
SolidBrush objBrush = null;
if (_penType == 0)
{
// ペンが選択されている場合
objPen = new Pen(Color.Black, 3);
objGrp.DrawLine(objPen, _prevX, _prevY, e.Location.X, e.Location.Y);
objPen.Dispose();
}
else if (_penType == 1)
{
// 四角形が選択されている場合
_newBitMap = (Bitmap)_oldBitMap.Clone();
objGrp = Graphics.FromImage(_newBitMap);
objBrush = new SolidBrush(Color.Black);
if (_startX <= e.Location.X)
{
if (_startY <= e.Location.Y)
{
objGrp.FillRectangle(objBrush, _startX, _startY, e.Location.X - _startX, e.Location.Y - _startY);
}
else
{
objGrp.FillRectangle(objBrush, _startX, e.Location.Y, e.Location.X - _startX, _startY - e.Location.Y);
}
}
else
{
if (_startY <= e.Location.Y)
{
objGrp.FillRectangle(objBrush, e.Location.X, _startY, _startX - e.Location.X, e.Location.Y - _startY);
}
else
{
objGrp.FillRectangle(objBrush, e.Location.X, e.Location.Y, _startX - e.Location.X, _startY - e.Location.Y);
}
}
objBrush.Dispose();
}
else if (_penType == 2)
{
// 選択ツールが選択されている場合
// 画像を途中で上書き保存しない
_newBitMap = (Bitmap)_oldBitMap.Clone();
objGrp = Graphics.FromImage(_newBitMap);
if (_moveImage == false)
{
// 画像範囲選択中のとき
objPen = new Pen(Color.Black, 1);
objPen.DashStyle = DashStyle.Dash;
if (_startX <= e.Location.X)
{
if (_startY <= e.Location.Y)
{
objGrp.DrawRectangle(objPen, _startX - 1, _startY - 1, e.Location.X - _startX + 1, e.Location.Y - _startY + 1);
}
else
{
objGrp.DrawRectangle(objPen, _startX - 1, e.Location.Y - 1, e.Location.X - _startX + 1, _startY - e.Location.Y + 1);
}
}
else
{
if (_startY <= e.Location.Y)
{
objGrp.DrawRectangle(objPen, e.Location.X - 1, _startY - 1, _startX - e.Location.X + 1, e.Location.Y - _startY + 1);
}
else
{
objGrp.DrawRectangle(objPen, e.Location.X - 1, e.Location.Y - 1, _startX - e.Location.X + 1, _startY - e.Location.Y + 1);
}
}
}
else
{
// 画像移動中のとき
if (_moveFirst == true)
{
// 初回の画像移動だった場合
// 切り取られた範囲を白で塗り潰す
objBrush = new SolidBrush(Color.White);
objGrp.FillRectangle(objBrush, _selectedRect);
objBrush.Dispose();
// 画像を更新する
_oldBitMap = (Bitmap)_newBitMap.Clone();
_moveFirst = false;
}
// DrawImage()で、選択された画像_selectBitMapを指定した位置に描画する
// DrawRectangle()で、選択範囲の枠を描画する
objPen = new Pen(Color.Black, 1);
objPen.DashStyle = DashStyle.Dash;
objGrp.DrawImage(_selectBitMap, _selectX + e.Location.X - _startX, _selectY + e.Location.Y - _startY, _selectBitMap.Width, _selectBitMap.Height);
objGrp.DrawRectangle(objPen, _selectX + e.Location.X - _startX - 1, _selectY + e.Location.Y - _startY - 1, _selectBitMap.Width + 1, _selectBitMap.Height + 1);
objPen.Dispose();
}
}
// BitMapオブジェクトをPictureBoxに表示する
objGrp.Dispose();
_prevX = e.Location.X;
_prevY = e.Location.Y;
DrawingPicBox.Image = _newBitMap;
}
}
private void Tools_CheckedChanged(object sender, EventArgs e)
{
// 現在の選択されているツールの種類を保存
if(typePen.Checked == true)
{
_penType = 0;
}
else if(typeSquare.Checked == true)
{
_penType = 1;
}
else if (typeSelect.Checked == true)
{
_penType = 2;
}
}
}
}
マウスドラッグで範囲を指定し、選択された範囲の画像を_selectBitMapへコピーしています
DrawImage()でコピーされた_selectBitMap(ビットマップ画像)を、そのまま描画できます
(Rectangleなどで描画する場所とサイズを指定する必要がある)