C#で作るグレースケールへ変換するコンソールアプリ

コンピュータ

コンソールで実行するシンプルな画像変換アプリを作りたいと思います。
C#でOpenCVSharpを使い画像ファイルをグレスケールに変換し、png形式で保存する外部コマンドになります。

image

ソースコード

ファイル名:grayconv.csproj


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="OpenCvSharp4" Version="4.11.0.20250507" />
    <PackageReference Include="OpenCvSharp4.runtime.win" Version="4.11.0.20250507" />
  </ItemGroup>

</Project>

ファイル名:Opt.cs


public class Opt
{
    public string Input { get; set; } = "";
    public string? Output { get; set; } = null;
    public static Opt ParseArgs(string[] a)
    {
        var o = new Opt();
        string? key = null;
        foreach (var token in a)
        {
            if (token.StartsWith("-"))
            {
                key = token;
            }
            else
            {
                switch (key)
                {
                    case "-i": case "--in": o.Input = token; break;
                    case "-o": case "--out": o.Output = token; break;
                    default:
                        // 位置引数互換
                        if (string.IsNullOrEmpty(o.Input)) o.Input = token;
                        else if (o.Output is null) o.Output = token;
                        break;
                }
                key = null;
            }
        }
        return o;
    }
    public static void PrintHelp()
    {
        Console.Error.WriteLine(
@"Usage:
  grayconv -i <input> [options]
  grayconv <input> [output.png]

Options:
  -i, --in <path>          入力ファイル
  -o, --out <path>         出力ファイル(省略時: <input>_gray.png)
");
    }

}

ファイル名:Program.cs


// C#で作るグレースケールへ変換するコンソールアプリ

// ビルドコマンド
// dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true /p:SelfContained=true --output "exeの出力先のディレクトリ"
using OpenCvSharp;

class Program
{
    static void Main(string[] args)
    {
        if (args.Length == 0 || args.Contains("-h") || args.Contains("--help"))
        {
            Opt.PrintHelp();
            Environment.Exit(1);
        }

        var opt = Opt.ParseArgs(args);
        if (string.IsNullOrWhiteSpace(opt.Input))
        {
            Opt.PrintHelp();
            Environment.Exit(1);
        }

        string output = opt.Output ?? Path.Combine(
            Path.GetDirectoryName(opt.Input) ?? "",
            Path.GetFileNameWithoutExtension(opt.Input) + "_gray.png");

        imageFilter(opt.Input, output);

        Console.WriteLine(output);
    }

    static void imageFilter(string inputPath, string outputPath)
    {
        using var src = Cv2.ImRead(inputPath, ImreadModes.Color);
        using var gray = new Mat();
        Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
        Cv2.ImWrite(outputPath, gray);
    }
}

ビルドコマンド

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true /p:SelfContained=true --output "exeの出力先のディレクトリ"

使用例

単体実行

grayconv -i .\入力ファイル.jpg

複数一括

カレントディレクトリの拡張子がjpgファイルをすべて処理

ls *.jpg | % { grayconv -i $_ }

複数一括・並列処理で高速化

処理順番が順不同でも問題ないので並列処理が出来ます。PowerShell 7以降

ls *.jpg | % -Parallel {grayconv $_} -ThrottleLimit 8

コメント