C#で画像ファイルをリサイズ(拡大・縮小)するCLIコマンド

C# コンピュータ
C#

コマンドラインから画像ファイルをリサイズ(拡大・縮小)します。

プロジェクトの作成

mkdir ImgResize
cd ImgResize
dotnet new console
dotnet add package System.CommandLine --prerelease
dotnet add package OpenCvSharp4
dotnet add package OpenCvSharp4.Windows
dotnet add package OpenCvSharp4.Extensions
dotnet add package OpenCvSharp4.runtime.win

ソースコード

using System.CommandLine;
using OpenCvSharp;

namespace ImgResize;
class Program
{
    static readonly string Suffix = "_Resize";
    static void Filter(FileInfo file, double scale, InterpolationFlags interpolationFlags, string dir)
    {
        // ファイルが存在しない場合戻る
        if (!File.Exists(file.FullName)) return;

        // 出力ディレクトリが無い場合入力ディレクトリをセット
        if (dir == "")
        {
            dir = file.DirectoryName ?? Directory.GetCurrentDirectory();
        }
        // 出力ディレクトリが無い場合作成
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }
        // 出力ファイルのパスを生成
        string fileName = file.Name;
        if (dir == file.DirectoryName)
        {
            // 入力と出力ディレクトリが同じ場合ファイル名にSuffixを付与
            fileName = Path.GetFileNameWithoutExtension(file.Name) + Suffix + file.Extension;
        }
        string outFile = Path.Join(dir, fileName);

        // 縮小の場合保管方法を変更
        if (scale < 1.0)
        {
            interpolationFlags = InterpolationFlags.Area;
        }
        
        // 画像ファイルを読み込み
        using var src = Cv2.ImRead(file.FullName);
        using var dst = new Mat();
        // リサイズ
        Cv2.Resize(src, dst, new OpenCvSharp.Size(0,0), scale, scale, interpolationFlags);
        // ファイルに保存
        Cv2.ImWrite(outFile, dst);
        // 標準出力に出力ファイルのパスを出力
        Console.WriteLine(outFile);
    }
    static async Task<int> Main(string[] args)
    {
        var fileOption = new Option<FileInfo?>(
            name: "--file",
            description: "入力画像ファイル",
            getDefaultValue: () => null
        ){ IsRequired = false };
        var scaleOption = new Option<double>(
            name: "--scale",
            description: "倍率",
            getDefaultValue: () => 0.5d
        ){ IsRequired = true };
        var interpolationFlagsOptions = new Option<InterpolationFlags>(
            name: "--InterpolationFlags",
            description: "補完方法",
            getDefaultValue: () => InterpolationFlags.Lanczos4
        );
        var dirOption = new Option<string>(
            name: "--dir",
            description: "出力先のディレクトリ",
            getDefaultValue: () => ""
        ){ IsRequired = false };
        var rootCommand = new RootCommand(
            "画像ファイルをリサイズ"
        );
        
        rootCommand.AddOption(fileOption);
        rootCommand.AddOption(scaleOption);
        rootCommand.AddOption(interpolationFlagsOptions);
        rootCommand.AddOption(dirOption);

        rootCommand.SetHandler((file, scale, interpolationFlags, dir) =>
            {

                if (Console.IsInputRedirected)
                {
                    // 標準入力リダイレクト有り
                    string? line = Console.ReadLine();
                    while (line != null)
                    {
                        // Fileオプションは無視
                        Filter(new FileInfo(line), scale, interpolationFlags, dir);
                        line = Console.ReadLine();
                    }
                }
                else
                {
                    // 標準入力リダイレクト無し
                    if (file is null) return;
                    Filter(file!, scale, interpolationFlags, dir);
                }
            },
            fileOption, scaleOption, interpolationFlagsOptions, dirOption);

        return await rootCommand.InvokeAsync(args);
    }
}
Download

コメント