表示画像を移動させる機能を付与しようとしましたが、前回作成のプログラムをベースに変更しようと試みましたが断念し、全面的に書き直しました。
前回の記事
プロジェクトの作成
mkdir プロジェクト名
cd プロジェクト名
dotnet new winforms -f net6.0
ソースコード
ファイル名:Form1.cs
using System.Drawing.Drawing2D;
namespace DualViewer2;
public partial class Form1 : Form
{
// 定数
const int _margin = 10;
// 右側のBitmap
Bitmap? rightBitmap = null;
// 右側のGrapichs
Graphics? rightGraphics = null;
// 右側のMatrix
Matrix? rightMatrix = null;
// 右側のマウス移動フラグ
bool rightIsMouseMoving = false;
// 右側のマウス座標
PointF rightMousePostion = new();
// 左側のBitmap
Bitmap? leftBitmap = null;
// 左側のGrapichs
Graphics? leftGraphics = null;
// 左側のMatrix
Matrix? leftMatrix = null;
// 左側のマウス移動フラグ
bool leftIsMouseMoving = false;
// 左側のマウス座標
PointF leftMousePostion = new();
// 左パネル
readonly Panel leftPanel = new()
{
BackColor = Color.LightBlue,
};
// 左ピクチャボックス
readonly PictureBox leftView = new()
{
Dock = DockStyle.Fill,
BackColor = Color.Blue,
AllowDrop = true,
};
// 右パネル
readonly Panel rightPanel = new()
{
BackColor = Color.LightGreen,
};
// 右ピクチャボックス
readonly PictureBox rightView = new()
{
Dock = DockStyle.Fill,
BackColor = Color.Green,
AllowDrop = true,
};
// コンストラクタ
public Form1()
{
// コンポーネント初期化
InitializeComponent();
// イベントの登録
this.Load += Form1_Load;
this.Resize += Form1_Resize;
leftView.DragEnter += LeftView_DragEnter;
leftView.DragDrop += LeftView_DragDrop;
rightView.DragEnter += RightView_DragEnter;
rightView.DragDrop += RightView_DragDrop;
rightView.MouseDown += View_MouseDown;
rightView.MouseMove += View_MouseMove;
rightView.MouseUp += View_MouseUp;
rightView.MouseWheel += View_MouseWheel;
leftView.MouseDown += View_MouseDown;
leftView.MouseMove += View_MouseMove;
leftView.MouseUp += View_MouseUp;
leftView.MouseWheel += View_MouseWheel;
}
// フォームロードイベント
void Form1_Load(object? s, EventArgs e)
{
rightPanel.Controls.Add(rightView);
leftPanel.Controls.Add(leftView);
this.Controls.AddRange(new Control[]{leftPanel, rightPanel});
this.Size = new Size(800, 600);
}
// フォームのリサイズイベント
void Form1_Resize(object? s, EventArgs e)
{
int width = this.ClientSize.Width;
int height = this.ClientSize.Height;
if (width == 0 || height == 0) return;
int w = (width - (_margin * 4)) / 2;
int h = (height - (_margin * 2));
leftPanel.Location = new Point(_margin, _margin);
leftPanel.Size = new Size(w, h);
rightPanel.Location = new Point(_margin*2 + w, _margin);
rightPanel.Size = new Size(w, h);
if (rightGraphics is not null) {
rightMatrix = rightGraphics.Transform;
rightGraphics.Dispose();
}
else
rightMatrix = new Matrix();
rightView.Image?.Dispose();
rightView.Image = new Bitmap(rightView.Width, rightView.Height);
rightGraphics = Graphics.FromImage(rightView.Image);
rightGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
leftView.Image?.Dispose();
leftView.Image = new Bitmap(leftView.Width, leftView.Height);
leftGraphics = Graphics.FromImage(leftView.Image);
leftGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
DrawImage();
}
// 左ビュードラグアンドドロップ
void LeftView_DragEnter(object? s, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
async void LeftView_DragDrop(object? s, DragEventArgs e)
{
if (e.Data == null) return;
Object? obj = e.Data.GetData(DataFormats.FileDrop, false);
if (obj == null) return;
var path = ((string[])obj)[0];
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
leftBitmap?.Dispose();
leftBitmap = await Task.Run(()=>(Bitmap)Bitmap.FromStream(fs));
rightMatrix?.Reset();
leftMatrix = new Matrix();
DrawImage();
}
// 右ビュードラグアンドドロップ
void RightView_DragEnter(object? s, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
async void RightView_DragDrop(object? s, DragEventArgs e)
{
if (e.Data == null) return;
Object? obj = e.Data.GetData(DataFormats.FileDrop, false);
if (obj == null) return;
var path = ((string[])obj)[0];
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
rightBitmap?.Dispose();
rightBitmap = await Task.Run(()=>(Bitmap)Bitmap.FromStream(fs));
rightMatrix = new Matrix();
leftMatrix?.Reset();
DrawImage();
}
// ビットマップの描画
void DrawImage()
{
if (rightBitmap is not null && rightGraphics is not null) {
if (rightMatrix is not null)
rightGraphics.Transform = rightMatrix;
rightGraphics.Clear(rightView.BackColor);
rightGraphics.DrawImage(rightBitmap, 0, 0, rightBitmap.Width, rightBitmap.Height);
rightView.Refresh();
}
if (leftBitmap is not null && leftGraphics is not null) {
if (leftMatrix is not null)
leftGraphics.Transform = leftMatrix;
leftGraphics.Clear(leftView.BackColor);
leftGraphics.DrawImage(leftBitmap, 0, 0, leftBitmap.Width, leftBitmap.Height);
leftView.Refresh();
}
}
// マウスダウンイベント
void View_MouseDown(object? sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right) {
rightMatrix?.Reset();
leftMatrix?.Reset();
DrawImage();
return;
}
if (rightBitmap is not null) {
rightView.Focus();
rightMousePostion.X = e.X;
rightMousePostion.Y = e.Y;
rightIsMouseMoving = true;
}
if (leftBitmap is not null) {
leftView.Focus();
leftMousePostion.X = e.X;
leftMousePostion.Y = e.Y;
leftIsMouseMoving = true;
}
}
// マウス移動イベント
void View_MouseMove(object? sender, MouseEventArgs e)
{
bool flag = false;
if (rightBitmap is not null && rightMatrix is not null) {
if (rightIsMouseMoving == true) {
float xx = e.X - rightMousePostion.X;
float yy = e.Y - rightMousePostion.Y;
rightMatrix.Translate(xx, yy, MatrixOrder.Append);
flag = true;
rightMousePostion.X = e.X;
rightMousePostion.Y = e.Y;
}
}
if (leftBitmap is not null && leftMatrix is not null) {
if (leftIsMouseMoving == true) {
float xx = e.X - leftMousePostion.X;
float yy = e.Y - leftMousePostion.Y;
leftMatrix.Translate(xx, yy, MatrixOrder.Append);
flag = true;
leftMousePostion.X = e.X;
leftMousePostion.Y = e.Y;
}
}
if (flag)
DrawImage();
}
// マウスアップイベント
void View_MouseUp(object? sender, MouseEventArgs e)
{
if (rightBitmap is not null)
rightIsMouseMoving = false;
if (leftBitmap is not null)
leftIsMouseMoving = false;
}
// マウスホイールイベント
void View_MouseWheel(object? sender, MouseEventArgs e)
{
bool flag = false;
if (rightBitmap is not null && rightMatrix is not null) {
rightMatrix.Translate(-e.X, -e.Y, MatrixOrder.Append);
if (e.Delta > 0) {
if (rightMatrix.Elements[0] < 100) {
rightMatrix.Scale(1.5f, 1.5f, MatrixOrder.Append);
}
} else {
if (rightMatrix.Elements[0] > 0.01) {
rightMatrix.Scale(1.0f/1.5f, 1.0f/1.5f, MatrixOrder.Append);
}
}
rightMatrix.Translate(e.X, e.Y, MatrixOrder.Append);
flag = true;
}
if (leftBitmap is not null && leftMatrix is not null) {
leftMatrix.Translate(-e.X, -e.Y, MatrixOrder.Append);
if (e.Delta > 0) {
if (leftMatrix.Elements[0] < 100) {
leftMatrix.Scale(1.5f, 1.5f, MatrixOrder.Append);
}
} else {
if (leftMatrix.Elements[0] > 0.01) {
leftMatrix.Scale(1.0f/1.5f, 1.0f/1.5f, MatrixOrder.Append);
}
}
leftMatrix.Translate(e.X, e.Y, MatrixOrder.Append);
flag = true;
}
if (flag)
DrawImage();
}
}
ビルド
dotnet build -c Release
機能
- フォームの左右に各々画像をファイルをエクスプローラーなどからドラッグアンドドロップで画像が表示
- マウスのホイールで画像の拡大縮小
- マウスのドラッグで画像が移動
説明
前回のコードでは拡大縮小するピクチャボックスベースのユーザーコントロールを作成しましたが、マウスイベントを2つのコントロールで連動させる方法が思いつかなかったので、シンプルに2つのピクチャボックス並べる方法にしてみました。
コメント