画像加工アプリケーションを作成します。
今回はメインとなるフォームにドラックアンドドロップで画像表示、Ctrl+Cでクリップボードへコピー、メニューで画像の拡大機能を作成してみました。
プロジェクトの作成
mkdir GazouKakou01
cd GazouKakou01
dotnet new winforms
ソースコード
ファイル名:Form1.cs
using System.Drawing.Drawing2D;
namespace GazouKakou01;
public partial class Form1 : Form
{
Bitmap? _buffBmp;
Bitmap? _viewBmp;
int _scale = 1;
public void ScaleChange()
{
if (_buffBmp is null) return;
int w = _buffBmp.Width * _scale;
int h = _buffBmp.Height * _scale;
_viewBmp?.Dispose();
_viewBmp = new (w, h);
using var g = Graphics.FromImage(_viewBmp);
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(_buffBmp, 0, 0, w, h);
}
public Bitmap? Bmp
{
get
{
return _viewBmp;
}
set
{
_buffBmp?.Dispose();
_buffBmp = value;
ScaleChange();
}
}
// メインメニュー
readonly MenuStrip menubar = new();
readonly ToolStripMenuItem viewMenuItem = new()
{
Text = "表示",
};
readonly ToolStripMenuItem expandX1MenuItem = new()
{
Text = "等倍",
Checked = true, // チェック
Tag = 1,
};
readonly ToolStripMenuItem expandX2MenuItem = new()
{
Text = "拡大2倍",
Checked = false, // 未チェック
Tag = 2,
};
readonly ToolStripMenuItem expandX4MenuItem = new()
{
Text = "拡大x4",
Checked = false, // 未チェック
Tag = 4,
};
readonly ToolStripMenuItem expandX8MenuItem = new()
{
Text = "拡大x8",
Checked = false, // 未チェック
Tag = 8,
};
// ステータスバー
readonly StatusStrip statusbar = new();
readonly ToolStripStatusLabel statusLabel1 = new();
// パネル
readonly Panel mainPanel = new()
{
Dock = DockStyle.Fill,
AllowDrop = true,
AutoScroll = true,
};
// ピクチャボックス
readonly PictureBox mainPicbox = new()
{
SizeMode = PictureBoxSizeMode.AutoSize,
};
public Form1()
{
InitializeComponent();
// キーボードイベントをFormで受け取る
this.KeyPreview = true;
// コントロールの登録
this.Controls.AddRange([
mainPanel,
menubar,
statusbar,]);
// メインメニューの登録
menubar.Items.Add(viewMenuItem);
viewMenuItem.DropDownItems.AddRange(new ToolStripItem[] {
expandX1MenuItem,
expandX2MenuItem,
expandX4MenuItem,
expandX8MenuItem,});
// ステータスバーを登録
statusbar.Items.Add(statusLabel1);
// ピクチャボックスを登録
mainPanel.Controls.Add(mainPicbox);
// ドラックアンドドロップ
mainPanel.DragEnter += (s, e) =>
{
e.Effect = DragDropEffects.Copy;
};
mainPanel.DragDrop += async (s, e) =>
{
if (e.Data is null) return;
var data = e.Data.GetData(DataFormats.FileDrop, false);
if (data is not string[] files) return;
this.Bmp = await Task.Run(()=>{
using var fs = new FileStream(files[0], FileMode.Open, FileAccess.Read);
var bmp = new Bitmap(fs);
return bmp;
});
mainPicbox.Image = this._viewBmp;
};
// キーボードイベント
this.KeyDown += async (s, e) =>
{
if (_buffBmp is null) return;
// Ctrl+C
if ((e.Modifiers & Keys.Control) == Keys.Control && e.KeyCode == Keys.C)
{
// クリップボードへ画像をコピー
var ms = new MemoryStream();
_buffBmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
Clipboard.SetData("PNG", ms);
statusLabel1.Text = "クリップボードへコピーしました。";
await Task.Delay(1000);
statusLabel1.Text = "";
}
};
// 拡大項目を選択
Action<Object?> scaleExec = new((obj)=>
{
if (obj is null) return;
if (obj is not ToolStripMenuItem menu) return;
foreach(ToolStripMenuItem m in viewMenuItem.DropDownItems)
{
if (m.Tag == menu.Tag)
{
m.Checked = true;
this._scale = (menu.Tag is null) ? 1 : (int)menu.Tag;
} else {
m.Checked = false;
}
}
ScaleChange();
mainPicbox.Image = this.Bmp;
});
// メニューアイテムのクリックイベント
expandX1MenuItem.Click += (s, e) => scaleExec(s);
expandX2MenuItem.Click += (s, e) => scaleExec(s);
expandX4MenuItem.Click += (s, e) => scaleExec(s);
expandX8MenuItem.Click += (s, e) => scaleExec(s);
}
~Form1()
{
_viewBmp?.Dispose();
_buffBmp?.Dispose();
}
}
実行
フォームに画像ファイルをドラックアンドドロップ
画像が表示されます。
メニューで拡大率を選択できます。
このほかにキーボードでCtrl+Cでクリップボードへ画像がコピーされます。
今後
画像の編集は基本的にGIMPで行っているのですが、GIMPに無いOpenCVのフィルターなどをアプリケーションに実装し、フィルターの結果をコピーしGIMPで貼り付けて連携するような使い方を想定しています。
過去の記事で試したOpenCVのフィルター類を一個のアプリケーションで呼び出せるような形になりますが、ソースコードが膨大になりそうですので、フィルターごとに一つのソースファイル(=記事)としてプロジェクトに追加していく予定です。
コメント