C#でImagemagickを使用して、JPEGファイルをまとめてリサイズする

名古屋サイクルトレンドに行ってきたのですが、一眼レフで写真を撮影すると解像度が大きすぎてそのままアップロードすると大容量なので、リサイズするexeを作ってみました。
指定したフォルダに入っているJPEGファイルをまとめてリサイズします。
巷ではそんなものは腐るほどあるのですが、手前味噌で作ってみました。

前提

Imagemagickのconvert.exeを使用してコマンドを投げているだけです。

http://www.imagemagick.org/:Imagemagickのサイトからダウンロードしてインストールしてみてください。

C#のソース

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;


namespace imagemagick_resize
{
    public class Program
    {
        static int Main(string[] args)
        {
            // オプション
            Options options = new Options();

            // args[]に入っているパラメータを取得する
            int i = 0;
            for (i = 0; i < args.Length; i++)
            {
                if (args[i].IndexOf("-") == 0)
                {
                    if (i + 1 > args.Length)
                    {
                        return -1;
                    }

                    switch (args[i])
                    {
                        case "-rsc":
                            options.resource = args[i+1];
                            break;
                        case "-dest":
                            options.destination = args[i+1];
                            break;
                        case "-resize":
                            options.resize = args[i+1];
                            break;
                        case "-prefix":
                            options.prefix = args[i+1];
                            break;
                        default: 
                            break;
                    }
                }
            }

            Program obj = new Program(options.resource, options.destination, options.resize, options.prefix);

            DateTime start, end;

            //パラレル処理
            System.Console.WriteLine("Start Parallel");
            start = DateTime.Now;
            obj.parallelExecute();
            end = DateTime.Now;
            System.Console.WriteLine("End Parallel");
            System.Console.WriteLine("Time(Sec): " + (end - start).TotalSeconds);

            if (obj.initialized == false)
            {
                return -1;
            }
            return 1;

        }


        DirectoryInfo resource;
        DirectoryInfo destination;
        const string imagemagic_convert_exe = @"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe"; // imagemagicのコマンド
        string resize;
        string prefix;

        bool initialized = false;
        public Program(string str_resource, string str_destination, string str_resize, string str_prefix)
        {
            if (!System.IO.Directory.Exists(str_resource))
            {
                System.Console.WriteLine("ディレクトリ" + str_resource + "が見つかりません。終了します。");
                return;
            }

            if (!System.IO.Directory.Exists(str_destination))
            {
                System.Console.WriteLine("ディレクトリ" + str_destination + "が見つかりません。終了します。");
                return;
            }

            // % | nxn | nx | xn
            // 50%, 640x480, 640x, 480x
            if (Regex.IsMatch(str_resize, "([0-9]{1,2}%|0-9]+x[0-9]+|x[0-9]+|[0-9]+x)", RegexOptions.IgnoreCase) == false)
            {
                System.Console.WriteLine("指定した引数が不正です。終了します。resize: " + str_resize);
                return;
            }

            if (str_prefix == string.Empty)
            {
                System.Console.WriteLine("指定した引数が不正です。終了します。");
                return;
            }

            initialized = true;
            resource = new DirectoryInfo(str_resource);
            destination = new DirectoryInfo(str_destination);
            resize = str_resize;
            prefix = str_prefix;
        }

        public class Options
        {
            public string resource { get; set; }

            public string destination { get; set; }

            public string resize { get; set; }

            public string prefix { get; set; }

        }

        public void parallelExecute()
        {
            if (this.initialized == false)
            {
                System.Console.WriteLine("初期化に失敗しました。終了します。");
                return;
            }

            //指定したディレクトリのjpegファイルを取得する
            FileInfo[] files = resource.GetFiles("*.jpg");
            
            Parallel.ForEach(files, file =>
            {
                //imagemagickのconvertコマンドを実行する
                Process ps = new Process();

                string rsc_jpeg = file.FullName;

                // 接頭辞をつけて、出力先ディレクトリを指定
                string dest_jpeg = this.destination.FullName + "\\" + this.prefix + file.Name;

                ps.StartInfo.FileName = imagemagic_convert_exe;       //コマンド
                ps.StartInfo.Arguments = "-resize " + this.resize.ToString() + " -quality 100 -verbose \"" + rsc_jpeg + "\" \"" + dest_jpeg + "\""; 
                ps.StartInfo.CreateNoWindow = true;
                ps.StartInfo.RedirectStandardOutput = true;
                ps.StartInfo.UseShellExecute = false;

                string cmd = ps.StartInfo.FileName + " " + ps.StartInfo.Arguments;

                System.Console.WriteLine("converting(" + file.Name + ")");
                //Debug.WriteLine(cmd);

                ps.Start(); //
                ps.WaitForExit();
                ps.Close();

            });
        }
    }
}

使い方

imagemagick_resize.exe -rsc "C:\Users\tn\Desktop\元データ" -dest "C:\Users\tn\Desktop\出力先" -resize 25% -prefix "resize_"

オプション引数

-rsc

元データのフォルダ。対象になったフォルダの拡張子が".jpg"のものをリサイズの対象にします。

-dest

出力先のフォルダ。もし元データのフォルダと同一の場合、上書きされるケースもありますよ。

-resize

リサイズする値。%もしくは、ピクセル指定(640x480、640x、x480)。

-prefix

元データのファイルに接頭辞を付けて、出力先フォルダにJPEGを出力します。何も変えたくない場合は""と指定します。

注意点

  • 指定したフォルダに同一ファイルがあった場合、勝手に上書きされます。
  • 拡張子は[.jpg]のみ対応。[.jpeg]とか対応していません。