エクスプローラーから、関連付けで起動し画像を確認、ペイントツールにつなげるツールです。
想定ユースケース
-
画像をダブルクリック
→ ImageLancher が起動
→ まず画像を確認 -
「これ、どのツールで編集しよう?」
→ コンテキストメニューから選択 -
MS Paint / GIMP / Krita / Photoshop
→ 設定ファイルで自由に差し替え
機能一覧
画像表示
-
ウィンドウサイズに合わせて表示(既定)
-
原寸大表示(1:1)
-
表示切り替えはコンテキストメニュー
クリップボード
-
表示中の画像をコピー
-
クリップボードの画像を貼り付けて表示
外部ツール起動
-
JSON 設定で定義された外部画像編集アプリを起動
-
メニュー項目は設定ファイルにより拡張可能
-
既定設定:MS Paint
ソースコード
App.xaml
<Application x:Class="ImageLancher.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ImageLancher">
</Application>
App.xaml.cs
using System.Linq;
using System.Windows;
namespace ImageLancher;
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
string? filePath = e.Args.FirstOrDefault();
var window = new MainWindow(filePath);
window.Show();
}
}
MainWindow.xaml
<Window x:Class="ImageLancher.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ImageLancher"
FontSize="16"
Width="900"
Height="700">
<Grid
Background="Black">
<Image
x:Name="ImageView"
Stretch="Uniform"
RenderOptions.BitmapScalingMode="HighQuality">
<Image.ContextMenu>
<ContextMenu
x:Name="ImageContextMenu">
<MenuItem
Header="ウィンドウに合わせて表示"
Click="FitToWindow_Click"/>
<MenuItem
Header="原寸大で表示"
Click="ActualSize_Click"/>
<Separator/>
<MenuItem
Header="画像をコピー"
Click="CopyImage_Click"/>
<MenuItem
Header="画像を貼り付け"
Click="PasteImage_Click"/>
<Separator/>
<!-- 外部ツールはコードで追加 -->
</ContextMenu>
</Image.ContextMenu>
</Image>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace ImageLancher;
public partial class MainWindow : Window
{
private BitmapSource? _bitmap;
private string? _filePath;
private readonly AppSettings _settings;
public MainWindow(string? filePath)
{
InitializeComponent();
_settings = SettingsLoader.Load();
_filePath = filePath;
if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
{
LoadImage(filePath);
}
BuildExternalToolMenu();
}
private void LoadImage(string path)
{
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.UriSource = new Uri(path);
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.EndInit();
bmp.Freeze();
_bitmap = bmp;
ImageView.Source = bmp;
}
// 表示切替
private void FitToWindow_Click(object sender, RoutedEventArgs e)
=> ImageView.Stretch = Stretch.Uniform;
private void ActualSize_Click(object sender, RoutedEventArgs e)
=> ImageView.Stretch = Stretch.None;
// クリップボード
private void CopyImage_Click(object sender, RoutedEventArgs e)
{
if (_bitmap != null)
Clipboard.SetImage(_bitmap);
}
private void PasteImage_Click(object sender, RoutedEventArgs e)
{
if (Clipboard.ContainsImage())
{
_bitmap = Clipboard.GetImage();
ImageView.Source = _bitmap;
_filePath = null;
}
}
// 外部ツールメニュー生成
private void BuildExternalToolMenu()
{
foreach (var tool in _settings.ExternalTools)
{
var item = new MenuItem
{
Header = tool.Name,
Tag = tool
};
item.Click += ExternalTool_Click;
ImageContextMenu.Items.Add(item);
}
}
private void ExternalTool_Click(object sender, RoutedEventArgs e)
{
if (_filePath == null) return;
var tool = (ExternalTool)((MenuItem)sender).Tag;
string path = Path.GetFullPath(_filePath);
var args = tool.Arguments.Replace("{file}", $"\"{path}\"");
Process.Start(new ProcessStartInfo
{
FileName = tool.Path,
Arguments = args,
UseShellExecute = true
});
}
}
Settings.cs
using System.IO;
using System.Text.Json;
namespace ImageLancher;
public class AppSettings
{
public List<ExternalTool> ExternalTools { get; set; } = new();
}
public class ExternalTool
{
public string Name { get; set; } = "";
public string Path { get; set; } = "";
public string Arguments { get; set; } = "{file}";
}
public static class SettingsLoader
{
private const string AppName = "ImageLancher";
public static AppSettings Load()
{
try
{
var dir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
AppName);
Directory.CreateDirectory(dir);
var path = Path.Combine(dir, "settings.json");
if (!File.Exists(path))
{
return CreateDefault(path);
}
var json = File.ReadAllText(path);
var settings = JsonSerializer.Deserialize<AppSettings>(json);
if (settings == null)
{
return CreateDefault(path);
}
return settings;
}
catch (Exception)
{
throw;
}
}
private static AppSettings CreateDefault(string path)
{
var settings = new AppSettings
{
ExternalTools =
{
new ExternalTool
{
Name = "MS Paint",
Path = "mspaint.exe"
}
}
};
File.WriteAllText(
path,
JsonSerializer.Serialize(settings,
new JsonSerializerOptions { WriteIndented = true }));
return settings;
}
}
実行例
起動するアプリはjsonファイルで設定可能です。
デフォルトはmspaint.exeがプリセットされます。
試しにコピーし、MS Paint2と名前を変更してみます。
setting.json
{
"ExternalTools": [
{
"Name": "MS Paint",
"Path": "mspaint.exe",
"Arguments": "{file}"
},
{
"Name": "MS Paint2",
"Path": "mspaint.exe",
"Arguments": "{file}"
}
]
}
スクリーンショット

コンテキストメニューに”MS Paint2″項目が増えました。
この方法でお好みのペイントソフトを追加することが出来ます。
setting.jsonの場所
%AppData%\ImageLancher\settings.json
筆者の環境
C:\Users\karet\AppData\Roaming\ImageLancher\settings.json
その他
アプリケーションアイコンの設定方法


C#のWPFでアプリケーションアイコンを設定する方法
・icoアイコンファイルの配置例:Assets/App.icoMyApp/ MyApp.csproj Assets/ App.ico・プロジェクトファイル(.csproj)<Project Sdk="Microsoft.NET.Sdk"> ...
Windows11のエクスプローラでファイルの関連付けを変更する方法。
jpgファイルを変更する例
- エクスプローラー→jpgファイルで右クリッリック→プロパティ

- PCでアプリを選択する→関連付けたいアプリの実行ファイルを選択

- 既定値を設定する

コメント