ImageMagick の例 --
Windows での使用方法
IM の例のほとんどのコマンドは、バッチ処理とネットワークサーバーを念頭に置いて設計された LINUX および UNIX シェルスクリプトを想定して記述されています。しかし、ImageMagick を Windows 環境で使用したいユーザーが増えています。このセクションでは、Windows 環境で IM を使用する方法、さらに重要なこととして、UNIX シェルコマンド (IM の例の残りの部分で使用されている) を Windows DOS の同等のコマンドに変換する方法について、詳細と例を示します。 Wolfgang Hugemann <ImageMagick_AT_Hugemann.de> 氏に特に感謝します。彼は元のメモを完全に書き直し、Windows ユーザーにとって特に重要な、より幅広いトピックを網羅するように拡張しました。ここに表示されているのは彼の作品であり、IM ユーザーは彼の時間と忍耐に感謝しています。
このコードは、IMがプログラムフォルダの下の "ImageMagick" というフォルダにインストールされていることを前提としていますが、これはインストールフォルダの**標準的な名前付けではありません**。(詳細はWindowsへのImageMagickのインストールを参照してください。)
簡潔にするために、このコードを毎回使用することはありませんが、良い習慣として覚えておいてください。 この問題の良い代替要約と解決策については、Ron Savage: MS Windows and convert.exeを参照してください。
しかし、これはWindowsでは目的の文字列を作成しません。 ただし、テキストファイルからUTF-8でエンコードされた文字列を読み取ることができます。
また、事前にコードページをUTF-8に切り替えれば、"
しかし、DOSコマンドの出力を処理する場合、たとえば特定のディレクトリに含まれるJPEGのインデックスプリントにそのディレクトリの名前をタイトル付けようとすると、問題が発生します。 コードページ65001への切り替えは、ほとんどのDOSコマンドでは機能しません。特にディレクトリツリーをループする場合です。 また、コードページを1252(西ヨーロッパ言語)と65001の間で切り替えることは、通常は機能しないか、少なくとも非常にトリッキーになります。 最も安全なアプローチは、外部コマンドラインプログラム、たとえばWindowsでも使用できるUNIXツール "
パラメータはIconvにISO-8859-1(コードページ1252)からUTF-8へのトランスコードを指示します。 Iconvは出力をstdoutに書き込むため、'label' で使用するにはファイルにリダイレクトする必要があります。 出力をテキストファイルにダンプすることをお勧めします。これは、ImageMagickにWindowsのバックスラッシュ("\ ")をエスケープ文字として使用せずに、ファイルの内容を文字通り解釈するように指示するためです。 もちろん、上記の例のコードは、デモンストレーションのためにここに提示されているため、あまり意味がありません。 実際的なDOSバッチファイルでは、ファイル名はFORループで生成される可能性があります。 実際的な例を以下に示します((サブ)ディレクトリツリーのバッチ処理を参照)。 UTF処理の詳細については、UnicodeまたはUTF8形式のテキスト処理の他のIMの例と情報をご参照ください。
は、
と同等です。 パイプの最初のコマンドでは、マイナス演算子はIMに画像を*stdout*に書き込むように指示し、パイプの2番目のコマンドのマイナス演算子はIMに画像を*stdin*から読み取るように指示します。 この手順により、一時ファイルの明示的な使用を回避できます。 特定のコマンドが特定の操作を提供していない場合、たとえばトリミングなどに特に役立ちます。
この機能の結果として、テキスト出力は通常*stdout*ではなく*stderr*に書き込まれます。 例:Compareのテキスト出力をテキストファイルにリダイレクトする場合、次のように記述する必要があります。
したがって、*stdout*("1>" または単に ">")ではなく、*stderr*("2>")をテキストファイルにリダイレクトする必要があります。
Cygwinを起動すると、そのBashシェルはDOSボックス、つまり黒い背景のテキストウィンドウによく似ています。DOSウィンドウと同様に、フォントはタイトルバーの左側にあるウィンドウのシステムメニューをクリックして選択できます。基本的なコマンドは次のとおりです。
は、Windows DOSバッチファイルとして次のようになります...
SED(Streaming EDitor)を使用して、基本的なLinuxシェルからDOSバッチファイルへのコンバーターを作成しました。SEDは一般的なUNIX / Linuxテキストファイル操作プログラムであり、Windowsでもhttp://sed.sourceforge.net/で入手できます。IMがコマンド駆動型画像マニピュレーターであるように、SEDはコマンド駆動型エディターです。必要な操作を実行するSEDスクリプト
完全にコメント化されたバージョンのファイルsed_script.zipをダウンロードできます。SEDスクリプト
次のバッチファイルを使用して、SendToまたはドラッグアンドドロップを介して変換を呼び出すこともできます。
このバッチファイルは、SEDスクリプト`cim.txt`をSEDのプログラムフォルダに配置していることを前提としています。コマンドラインパラメータとしてLinuxシェルスクリプトのファイル名を受け取り、同じ名前で拡張子が`.bat`のバッチファイルを同じフォルダに生成します。(不可解なファイル名操作`"%~dpn1.bat"`については、次のセクションで説明します。)注意:上記のSEDスクリプトは、上記の基本的な置換のみを実行します。Fred Weinhausのウェブサイトで紹介されているような洗練されたLinuxシェルスクリプトを、同等のバッチファイルに変換することはできません!
`PAUSE`ステートメントのため、ユーザーがキーを押すまでDOSボックスは開いたままになり、結果を確認できます。スペースを含むファイル名で上記を試すと、ファイル名が二重引用符で囲まれていることがわかります。ここで、以降のすべての例では、ネットワークファイルにドライブ文字が割り当てられていることを前提としていることに注意してください。実際には、ローカルの商用ネットワークで異なる動作を見たことはありません。バッチファイルを使用する場合、UNC名を処理しようとしないでください。バッチは動作するかもしれませんが、不必要なトラブルが発生します。このファイル名をConvertコマンドラインで使用すると、この動作が問題を引き起こす可能性があります。他の形式からJPEGへの簡単な変換を実行してみましょう。最も基本的なコードは次のとおりです。
これにより、標準の品質と解像度で、同じディレクトリに`.jpg`拡張子が追加されたJPEGファイルが生成されます。上記のコードは、スペースを含むかどうかに関係なく、すべてのファイル名で機能します。元の拡張子を削除したい場合は、少し複雑になります。
上記のバッチファイルは、`~`演算子を使用してファイル名を操作します。
これらの修飾子は組み合わせることができ、`"%~dpn1"`は「拡張子と括弧の引用符のないドライブ+パス+名前」を意味します。したがって、スペースを含むファイル名でもコードが機能するように、名前を二重引用符で囲む必要があります。(そうでない場合、引用符は無害です。)`PAUSE`ステートメントはテスト目的のみであり、最終的なバッチファイルでは削除できます。IMを実際に呼び出さずにコードをテストしたい場合は、次のように記述する必要があります。
これは、文字列操作の結果のみを表示します。
パーセント記号が2倍に**なっていない**ことに注意してください。ただし、このコマンドをバッチファイルに配置する場合は、次のように置き換える必要があります。
繰り返しになりますが、ドラッグ&ドロップまたは送信先に渡すことにより、完全修飾ファイル名(またはフォルダ名)を、別のディレクトリ(`shell:sendto`など)にある可能性のあるDOSバッチファイルに渡すことで、この一括操作を呼び出すと便利です。この場合、最初のステップでファイルのディレクトリをカレントディレクトリにする必要があります。
このバッチファイルでは、次の操作を行います。
これは、少し短くなるかもしれませんが、はるかにトリッキーになります。ファイル名修飾子は、Forループ変数`%%a`でも機能することに注意してください。注2:最後のバックスラッシュはパス名の一部です。したがって、`"%~dp1small"`でなければならず、コードを読みやすくしない`"%~dp1\small"`であってはなりません。特に` "%%~dpasmall\%%~nxa"`の場合には当てはまります。`FOR`ステートメントには、いくつかの欠点と注意点があります。その1つは、基本的に`DO`の後に1つのコマンドのみを実行することです。ただし、一連のDOSコマンドを括弧「(」、「)」でグループ化することにより、単純なコマンドシーケンスを実行できます。
このバッチファイルは、コマンドライン引数として渡されたディレクトリにあるすべての画像を処理します。最初に元の画像をぼかして反転し、中間結果を`.miff`拡張子が追加されたファイルに保存します。次に、元の画像をこの変更されたバージョンに重ね合わせることにより、元の画像の暗い部分を明るくします.最後に中間画像が削除されます.上記では、**単純なコマンドシーケンス**を強調する必要があることに注意してください。ブロック内で`GOTO`ジャンプを使用することはできません。このような動作が必要な場合は、`FOR`ループで別のバッチファイルを呼び出す必要があります。
ここで、`process.bat`は実際の作業を行うバッチファイルであり、呼び出し元のバッチファイルと同じディレクトリにあります。コマンドラインパラメータ0(`"%0"`)はバッチファイル自体の名前であるため、`"%~dp0process"`は同じディレクトリにあるバッチファイル`process.bat`を呼び出します。`FOR`ステートメントはファイル名のみを提供し、これは`"%~fa"`を介して完全修飾ファイル名に変換されます。この場合、バッチファイル`process.bat`のコードは、上記の例で括弧の間に配置されたコードと同じになります.
ただし、別のバッチファイルを使用すると、DOSバッチファイルのすべての(制限された)可能性が提供されます。この例では違いはありませんが、このアプローチの利点を以下に示します。2つのバッチファイルに煩わされたくない場合は、スクリプトに2番目の`process.bat`スクリプトを作成させ(`ECHO`を使用)、メインループから呼び出して、ジョブが完了したら削除することができます.
`ECHO`コマンドを使用する場合、すべての特殊なDOS文字、特にパーセント記号を2回エスケープする必要があります。そして、そうです、IMは上記のすべてを単一の処理コマンドで実行でき、`.miff`中間画像の必要性をなくすことができましたが、それはこの例のポイントではありません。
`/R`フラグを使用すると、ファイルをソートまたはフィルタリングするオプションなしで、常にサブディレクトリツリー全体をループします。次の例では、すべてのサブディレクトリのフォトインデックスプリントを生成し、ルートディレクトリ内に配置します。これは、Windowsエクスプローラーのプレビューと同様に、特定の写真を視覚的に検索する簡単な方法を提供しますが、検索ごとにディレクトリツリー全体を(時間のかかる)再スキャンする必要はありません。最初に、2つのバッチファイルを使用して問題に取り組みます。1つはループを実行し、もう1つは実際の作業を実行します。インデックスプリントは、`IDX_0001.jpg`、`IDX_0002.jpg`、`IDX_0003.jpg`などの低品質のJPEGファイルになります。最初にループを確立します.
最初の行は、以前の検索結果をすべてクリーンアップします。2行目では、`IDX_nnnn.JPG`ファイル名の生成に使用する環境変数COUNTを定義します。3行目では、`DIR /S /B /AD`を介してすべてのサブディレクトリのリストを作成し、「Porsche」という単語を含むディレクトリを抽出します(オプション`/I`を使用して大文字と小文字を区別しない)。そして、このフィルターされたリストをソートします。ソートすることにより、IDXファイルの番号順がディレクトリパス名のアルファベット順と一致することが保証されます。オプション`"delims="`は、最初の空白の後に 줄 바꿈 を切り捨てる標準の動作を抑制します。バッチファイル`C.BAT`を呼び出すときは、空白が正しく処理されるように、パス名を引用符で囲みます。最後の行では、バッチファイル`C.BAT`によって作成された一時ファイルを削除します。次に、実際の作業に移ります.
最初の行では、コードページを西ヨーロッパ語ラテン語(ISO-8859-1)に切り替えます。2行目では、ディレクトリに実際に写真が含まれているかどうかを確認し、そうでない場合はバッチの残りをスキップします。(代わりにバッチの残りの部分を実行しても、`magick montage`は単に出力を生成しないため、害はありませんが、IDXファイルの数は連続しなくなります。)Windows XP以降、適切なラベルを定義せずに実行を終了できる特別なGoToターゲットラベル`:EOF`があります。次に、`COUNT`を増分し、いくつかの先行ゼロを付加し、`%TFILE:~-4%`を介して最後の4文字を抽出して`TFILE`という名前のインデックスファイルを生成し、連結して`IDX_nnnn.jpg`形式のファイル名を作成します。`SET /A`ステートメントを使用して計算を実行する方法については、後述のSETを使用した計算で説明します。以下の行では、パス名`PNAME`を引用符から解放し、結果を中間ファイル `temp.txt`に格納します。これは`Icon.exe`を使用してUnicode(UTF-8)にトランスコードされます。(文字エンコーディングを参照)。次に、`title.txt`に格納されているUnicode文字列がIMのMontageによって読み取られます。これにより、文字列が文字通りに扱われるため、Windowsパス名でバックスラッシュをエスケープする必要がなくなります。次に、Montageは写真を6行ずつ(`-tile 6x`)組み合わせ、パス名でタイトルを付けます。結果のインデックスプリントの幅は1260ピクセルになり、ストレージの需要を減らすために30%のJPG品質で保存されます。最後の行では、プログラムJHEADを使用して、パス名をJPEGコメントに書き込みます。これにより、Windowsエクスプローラー内で、ファイル名内の特定の部分文字列をテキスト検索することにより、インデックスプリントをフィルタリングすることができます。2つのバッチファイルを組み合わせて、「作業バッチ」のコードを`FOR`ループに配置できます.
基本的に、初期コードに2つの変更を適用する必要があります.
ただし、より確実な方法は、バッチ自体で
これにより、ドラッグ&ドロップで渡された任意の数の画像をモンタージュできます。
上記のコードは、コマンドラインパラメータとして渡されたファイルが同じディレクトリにあり、ファイル名の英数字順にモンタージュする必要があることを前提としています。これは、たとえば、撮影時間順に並べ替えられるデジタル写真のインデックスに適しています。最初にファイルのディレクトリをカレントディレクトリにします。これにより、以降のコードが大幅に簡素化されます。次に、ファイル名を
最初の行では、2 番目のコマンドラインパラメータが存在するかどうかを確認します。存在する場合、すべてのコマンドラインパラメータ(%*)が処理されます。1 つのファイルだけがスクリプトに渡された場合、パターンはすべての JPEG ファイルに設定されます。この単純なパターンマッチでは、現在のドライブ(%~d1 経由)と現在のフォルダに変更する必要があります。つまり、
このスクリプトは、可能なすべての アルファ合成方法 を使用して 2 つのグラデーション画像を合成するため、演算子が画像の色にどのように影響するかを確認できます。生成される画像の一部のみが上記に示されています。これは 合成テーブル 用に生成された画像に似ているため、演算子が画像の色にどのように影響するかを確認できます。上記の行はバッチファイルであると想定されているため、パーセント記号を 2 倍にする必要があります。上記のスクリプトは、最初に、グレースケール範囲全体をカバーするグラデーションを持つ 2 つの直交(直角に配置)グレースケール画像を作成します。IM コマンド
UNIX シェルスクリプトを使用した上記の例と同様の例は、せん断を使用した等角立方体 にあります。このバッチファイルは、色空間をコマンドラインパラメータ "
また、DOS でパイプ処理することで
この例では、出力から "RGB" を含む行をフィルタリングし、ファイル
この場合、パイプ記号 "
このバッチファイルには、完全修飾ファイル名がコマンドラインパラメータ "
同じ
上記のバッチファイルでは、写真のファイル名が単一のコマンドラインパラメータとして提供され、"
コロン('
これにより、1 回の ImageMagick コマンド呼び出しから DOS 変数 '
最初の行では、写真の短い方の寸法を "
FX式は数値を生成できるだけでなく、より大きな文字列に埋め込まれた複数の数値を生成することもできます。たとえば、角丸の境界線では、画像の幅と高さの情報に基づいて複雑な描画文字列を直接生成するために使用されました。この追加機能と、他の外部プログラムへの依存を回避することで、この方法はバッチスクリプトで計算を実行するためのより好ましい方法になります。
このバッチファイルの例では、日付時刻文字列の色を、配置される領域の平均輝度(
最初の行では、ImageMagickのバージョンを照会し、標準出力を
Find(大文字と小文字を区別しないオプション/ Iで呼び出される)が文字列を見つけられない場合、ERRORLEVELを設定します。より洗練されたアプローチでは、PATHに依存しなくなる代わりに、レジストリエントリを確認できます。
このコードでは、IMのレジストリキー
画像は、スクリプトの最初の行でテストされる単一のコマンドラインパラメータとしてスクリプトに渡されます。以下では、ステートメントの前後に環境変数
ただし、これは、小数点が小数点に設定されているWindowsバージョンでのみ機能します。これは、時刻がロケールに従って提供され、fxが米国スキームに従って計算を実行するためです。 VBScriptとは対照的に、バッチファイル内でロケールを変更する方法はありません(レジストリを介してマシン全体で変更する場合を除く)。代わりに、時間全体を100分の1秒にmagickすることができます。これは、整数演算と同様に、後で差を計算することでも実行できます。基本的なコードは次のとおりです。
分割されたタイムコードの各部分の前に挿入された「1」は、先行ゼロを持つ数値が8進数として(誤って)解釈されるのを防ぎます。この方法で発生する「計算エラー」は、後で最後に36610100を引くことで補償されます。完全な(そしてより洗練された)サンプルコードはこちらにあります。別のアプローチは、Windows 2003 Ressource Kitで提供されている*TimeIt*ユーティリティです。こちらからダウンロードできます。ただし、正式にはWindows XPのみをサポートしています。
最初の行では、ロケールを米国英語(1033)に設定します。これにより、(とりわけ)小数点記号が小数点に設定されます。そうでない場合、小数値はロケールに従って表示されます。つまり、小数点ではなく小数点カンマが使用される可能性があり、そのような値がIMに渡されると問題が発生します。文字列定数の定義後の2行は標準的なオーバーヘッドです。`Exec`メソッドまたは`Run`メソッドを介してIMのプログラムを起動するには、常に`Shell`オブジェクトが必要になるためです。唯一のスクリプト引数はファイル名であり、通常はドラッグアンドドロップまたは送信先を介して提供します。出力ファイルに名前を付けるときは、PTlensと同様に、元のファイル名に "_pt" を追加します。たとえば、*Photo.JPG → Photo_pt.JPG*です。ファイル名は`strFileIn`に格納され、そこから出力ファイル`strFileOut`の名前を派生させます。次に、IMのIdentifyプログラムを実行します。結果(つまり、焦点距離を表すEXIF有理数)は`strf`に格納されます。EXIF有理数は、分子/分母として提供されます。たとえば、82/10 = 8.2 mmです。したがって、パラメータ*b*を計算する式で使用する前に、有理数を評価する必要があります。最後の2行では、Convertコマンドラインを作成し、ShellオブジェクトのRunメソッドを介してステートメントを実行します。パラメータ7はウィンドウを最小化し、TRUEはスクリプトに結果を待つように指示します。上記のスクリプトは、IMのコマンドラインツール(COM+オブジェクトではなく)でVBScriptを使用する場合の一般的な戦略の概要を示しています。これらは、次のように呼び出されます。
しかし、VBSコードはより分かりやすく、変更が容易であり、エラーチェックなどに関して簡単に拡張できます。2番目のFORステートメントでは改行ができないため、そのままにしておく必要があることに注意してください。
スクリプトは最初に、ドラッグアンドドロップを介してスクリプトに渡されたファイル名を連結します。次に、単純な文字列操作によって、同じフォルダー内のJPEG出力ファイルの名前を派生させます。最後に、適切なパラメータを使用してMontageが呼び出されます。より大きなスクリプトの場合、ファイル名を配列に格納すると便利です。
最初に`Dim FName()`を介して動的配列を定義し、次に`Redim FName(NArgs-1)`を介してサイズを変更します。入力ファイルリストでは各ファイルが完全修飾ファイル名で指定されているため、Montageのコマンドラインは非常に長くなる可能性があります。最大長は通常の8192文字では**なく**、ShellExecute関数の呼び出しに許可される最大長によって決まります。これはWindows XPでは2048文字にすぎません。ディレクトリ名が非常に長い場合、これは問題を引き起こす可能性があります。エラーはスクリプトが実行される**前**に発生するため、スクリプトによって処理することは**できません**。考えられる解決策は、ファイル名を短いローカルフォルダーに配置することです。スクリプトベースの(部分的な)解決策は、バッチファイルの場合と同じです。ファイル名が1つだけ指定されている場合は、親ディレクトリ内のすべての画像が処理されます。フォルダー内のすべてのGIFを処理するには、次のようなことができます。
ここでは、FileSystemオブジェクトを使用して親フォルダーの名前を決定します。ただし、FilesオブジェクトはTypeプロパティのみを提供するため、ファイル拡張子の一致は通常どおりにチェックされます。多くの場合、ドラッグアンドドロップまたは送信先はファイル名をランダムな順序でスクリプトに渡すため、ファイル名をアルファベット順に並べ替える必要があります。これは、バブルソートによって実現できます。
上記の概念のより洗練されたアプリケーションが右側に示されています。VBScriptとImageMagickを使用して、一連のビデオフレームが2つの平行な「フィルムストリップ」にマウントされています。パーフォレーションは、フレームの進行が、通常の西洋の読書パターンである左から右、次に上から下とは対照的に、上から下、つまり列ごとであることを視覚的に示唆しています。ジョブを実行するスクリプト全体は、アーカイブstrip.zipからダウンロードできます。補足:各フレームの右上にある赤いタイムコードは、AVIsynthスクリプトによって生成されました。フレームは、VirtualDubからエクスポートすることによってダンプされました。埋め込まれたタイムコードを使用すると、フレームは必ずしも時間的に等距離である必要はなく、つまり、Windowsエクスプローラーで必要に応じて選択し、SendToフォルダーにあるスクリプトに送信できます。
第二概念の有用な応用例として、Fred Weinhaus氏のウェブサイトで実演されている、ターゲット平面への画像の透視投影マッピングがあります。この概念を使用して、右に示すように、透視歪みのある画像を透視的に(ほぼ)正しいバージョンに「スキン」することができます。上部では、左の画像は軽微な事故現場で撮影された写真です。右の写真は、後日、やや高い位置から現場を訪れて撮影されたものです。下部では、事故写真(つまり平面の路面)が、透視変換によってターゲット写真にマッピングされています。(これは、黒い車の右前輪が残したかすかなスキッドマークの向きを視覚化することを目的としています。) このタスクを実行するには、ユーザーはソース画像内で4つの点と、透視的に正しい画像内の対応するターゲット点を選択する必要があります。IrfanViewのような画像ビューアで点を選択し、それらの座標をメモして、Convertコマンドラインに提供することで、手動で行うことができます。しかし、この面倒な作業は、フリーウェアプログラムWinMorphによって簡略化できます。WinMorphは、まさにこれを行うための便利なインターフェースを提供します。2つの画像からソースポイントと対応するターゲットポイントを選択します。2枚の写真にある黄色のポリラインは、それぞれの写真で選択された4つの点を結んでいます。ただし、モーフィングアルゴリズム自体は、透視補正を実行するのには適していません。(このアルゴリズムの基本的な機能は、IMウェブサイトの使用方法セクションの歪み部分で説明されています。モーフィングへの使用可能性のデモンストレーションは、Fred Weinhaus氏のShapeMorphスクリプトにあります。) WinMorphは、ソースとターゲット両方のファイル名、およびソースとターゲットの点の座標を含む(他の情報の中でも)構造化テキストファイルに情報を保存します。したがって、IMの透視歪みに必要なすべての情報をWinMorphファイルから取得できます。関連するすべてのファイルと画像のコピーは、wmpr.zipファイルからダウンロードできます。
ここでは、コマンドプロセッサcmdを/cオプションで呼び出して、完了時にコマンドボックスを自動的に閉じます。デバッグの目的で、/kオプションを使用して呼び出すこともできます。これにより、コマンドボックスが開いたままになり、発生したエラーメッセージを読み取ることができます。
はじめに
Windows PC で IM スクリプトを使用するメリットは?
以下の例では、基本的に IM をネットワークに接続された Windows デスクトップコンピューターで実行することを前提としています。Adobe Photoshop、Corel の Paint Shop Pro、IrfanView (http://www.irfanview.com/)、さらには GIMP (http://www.gimp.org/) など、すぐに利用できる画像操作プログラムはたくさんあります。では、なぜ IM のコマンドラインプログラムとスクリプトで画像処理を行う必要があるのでしょうか?マウス駆動型インターフェースの代わりに ImageMagick を使用する真の利点は、単一ファイルまたは大量のファイルに対して、ルーチン操作を完全に自動化できることです。次のようなタスクがあります。-
- 一括フォーマット変換
- これは、IrfanView など、かなりの数の Windows プログラムで提供されています。ただし、画像形式に関する IM の汎用性は他に類を見ません。たとえば、PDF のすべてのページを JPEG のシーケンスに変換できます (コンピューターに GhostScript がインストールされている場合)。
- デジタル写真の縮小と前処理
- デジタル写真をワードプロセッサドキュメントに埋め込む場合は、通常、解像度を下げてドキュメントを高速に印刷できるようにする必要があります。FreePDF などの PDF プリンタードライバーを使用してドキュメントを PDF に変換する場合も同様です。前処理には、色補正とレンズ補正ルーチンも含まれる場合があります。
- ロゴを大量のデジタル写真に配置する
- 一連の操作を大量のデジタル写真に適用する
- マウス駆動型プログラムを使用して一連の作業手順を作成したら、将来のバッチ処理のためにこれらの手順を自動化したい場合があります。ただし、スクリプト言語 (Adobe の Action Script など) は、Windows の画像処理プログラムではあまり一般的ではありません。
- 複数の画像をカタログ画像に結合する
-contrast-stretch
" で行われるように、正規化とコントラストストレッチ を参照)。IM スクリプトは、企業ネットワークでの生産的な使用に特に適しています。なぜなら、既製のスクリプトは誰でも適用できるからです。エンドユーザーはバックグラウンドで何が起こっているかを知る必要はありません。したがって、画像の標準的なワークフローステップを完全に自動化 (そして本当に標準化) することができます。以下に示すスクリプトのいくつかは、私たちの小さな会社 (事故再現の分野で働いている) での生産的な使用のために派生したものです。私は優れた Windows スクリプトプログラマーでも、IM のコマンドラインツールに最も精通しているわけでもありません。以下で扱う問題のいくつかには、おそらくより洗練されたアプローチがあります。私が指摘したい点は次のとおりです。- IM のコマンドラインツールを使用した Windows スクリプトプログラミングの基本的なテクニックをいくつか示すこと。
- IM ベースのスクリプトの使用は、芸術のための芸術でも、学問的な娯楽でもないことを証明すること。
- IM のコマンドラインツールは、ローカルネットワーク (Web サーバーだけでなく) で実際に機能することを示すこと。
IM コマンドラインツールの使用可能な環境
Windows では、単純な IM コマンドは通常、Windows コマンドシェル ( "DOS シェル"、cmd.exe
を起動して実行) で実行されます。長いコマンドラインまたは一連のコマンドラインで実行される複雑な操作の場合は、スクリプトを作成することをお勧めします。一連の単純なコマンドの場合は、Windows コマンドシェルで実行される DOS バッチファイルになる可能性が高くなります。ただし、このアプローチには欠点があります。バッチファイルコマンドセットは、一般的な UNIX コマンドシェルと比較してかなり制限されているためです。Windows で IM を実行する場合、基本的には次の選択肢があります。- Windows コマンドシェル ( "DOS ウィンドウ")
- これは、Windows NT 4.0、Windows XP 以降のバージョンで
cmd.exe
(32 ビットモード) によって実行され、どの Windows コンピューターにも存在します。DOS シェルとバッチファイルの使用、およびConvert コマンドの問題点に関する特別な注意を参照してください。 - Cygwin
- bash に似たコマンドシェル (http://www.cygwin.com/)。このシェルを使用すると、UNIX スタイルのコマンドラインシェルにアクセスできるため、この使用セクションの残りの部分で示されている IM の例は、指定どおりに実行できます。以下のCygwin の使用を参照してください。
- Windows Script Host
- Windows Script Host は .COM テクノロジに基づいています。これは、現代の Windows コンピューターに存在し、WSH スクリプトは単純な DOS バッチファイルよりもはるかに強力です。Windows Script Host は、VBScript (Visual Basic Script) と JScript (Java Script) が最も一般的な、いくつかのプログラミングインターフェースを提供します。IM コマンドラインツールは、Shell オブジェクトの DOS シェルコマンド
Run
またはExec
を使用して起動できます。以下のVisual Basic Script (VBS)を参照してください。 - Windows Powershell
- .NET 2.0 テクノロジに基づく、古代の DOS シェルの後継機です。Powershell は Windows 7 に付属しており、
powershell.exe
によって実行されます。Windows XP および Vista 用は、Microsoft の Web サイトからダウンロードできます。
スクリプトを効果的に実行する方法
入力ファイルの名前をコマンドラインパラメーターとして受け取り、何らかの操作を実行し、結果を単一の画像または一連の画像として出力する、完璧な Windows スクリプト (DOS バッチファイル、VBScript など) があるとします。毎回 DOS コマンドシェル (または代替手段) を起動して、スクリプトにファイル名を入力して提供するのは好きではないでしょう。このような面倒な手順を回避するために、基本的に **ドラッグアンドドロップ** または **SendTo** を使用できます。 **ドラッグアンドドロップ** を使用する場合、DOS バッチファイルまたは VBScript (またはその他) を、デスクトップや処理する画像ファイルが格納されているディレクトリなど、簡単にアクセスできる場所に配置します。次に、Windows エクスプローラーで処理するファイルを選択し、スクリプトファイルにドロップするだけです。ファイル名はコマンドラインパラメーターとしてスクリプトに渡され、スクリプト内で参照できます。代わりに、スクリプト (またはスクリプトへのリンク) を **SendTo** フォルダーに配置できます。このフォルダー内のプログラムは、エクスプローラーのファイルペインを右クリックすると、Windows エクスプローラーのコンテキストメニューに表示されます。ここでも、選択したファイルの名前はコマンドラインパラメーターとしてスクリプトに渡されます。SendTo フォルダーの名前はSendTo
です。その場所は、新しい Windows バージョンごとに移動するようです。それを見つけるための確実な方法は、実行ボックスに shell:sendto
と入力することです。Windows XP 以降の単一のコマンドラインは、8192 (= 213) 文字の長さにすることができます。したがって、コマンドラインから IM ツールを直接起動する場合、直接または必要なすべてのファイルを直接指定するバッチファイルを介して起動する場合、この制限に達することはほとんどありません。ただし、ドラッグアンドドロップは ExecShell ルーチンを使用します。これは "わずか" 2048 (= 211) 文字の文字列に制限されています。すべてのファイルは完全修飾ファイル名 (つまり、ドライブ + パス + 名前) で渡されるため、パス名が長すぎると、WSH 経由で実行されるバッチファイルと VBScript で問題になる可能性があります。このエラーは、スクリプトが実際に実行される **前** に発生するため、発生したらスクリプトで適切に処理できません。Windows XP での解決策は通常、パス名が短くなる場所にファイルを配置することです。Convert コマンドの問題点
IMのWindowsインストーラーは、IMのプログラムディレクトリを検索パスに追加します。そのため、パス名を指定せずに、コマンドプロンプトからIMのコマンドラインツールを直接呼び出すことができます。 デフォルトでは、コマンドラインツールとして`magick`を使用します。しかし、レガシープログラム名を選択すると、IMのコマンドラインツールの名前は非常に一般的になり(例:convert、identify、compareなど)、他のプログラムとの名前の競合が発生します。 特に、convertはWindowsシステムツールであり、Windowsシステムディレクトリ(c:\Windows\system32\convert.exe
)にあり、FAT32ファイルシステムを現在一般的なNTFSに変換します。 しかし、"convert.exe"という名前の他のプログラム、例えばDelphiレポートコンバーターユーティリティも存在します。FAT→NTFS変換ツールはWindows XPで初めて搭載され、IMのコマンドラインツール "convert
" との名前の競合が発生しました。IMのプログラムディレクトリがDOS検索パス(つまりPATH環境変数)に**追加**されたため、システムツールが最初に検出され、古いスクリプトで "magick
" を単純に呼び出すと正しく解決されませんでした。 しかし、IMのWindowsセットアッププログラムの現在のバージョンでは、IMのプログラムディレクトリを検索パスの先頭に配置することで、競合する名前の場合にIMのコマンドラインツールが通常最初に検出されるようにしています。 しかし、同じ名前の他のユーティリティ(例:Deplhiのレポートコンバーター)も同じ問題に遭遇し、同じ解決策、つまりプログラムパスをパス変数の先頭に配置することを採用しました。これは、この解決策が万能ではないことを意味します。DelphiがIMの後にインストールされている場合、Convertを単純に呼び出すと、IMのConvertではなく、レポートコンバーターツールが起動されます。Windows XPでConvertツールが導入されたことで、多くのレガシースクリプトがクラッシュしました。一般的な解決策は、IMのConvertツールを "IMconvert
" など、別の名前に変更することでした(システムコマンドの名前を変更することはできません。次のWindowsサービスパックでは、名前が変更されたバージョンを無視して、おそらく元の名前が復元されるためです)。 この解決策は現在不要ですが、インターネット上ではまだ見つけることができます。 将来の名前の競合を回避する最良の解決策は、スクリプト内でIMのコマンドラインツールを完全パス名で呼び出すことです。 つまり、その場所を変数または定数に格納することです。そのため、すべてのバッチファイルは次のような行で始める必要があります。
|
%PROGRAMFILES%
は、プログラムディレクトリの名前、つまり英語版Windowsでは "Program Files"、ドイツ語版Windowsでは "Programme" に展開される環境変数です。 SETLOCAL
は、新しい環境変数(IMCONVなど)の定義をバッチファイルのスコープに制限します。 EnableDelayedExpansion
はここでは実際には必要ありませんが、SETLOCAL
を使用するたびにこのオプションを使用することをお勧めします。詳細はバッチプログラミングのガイドラインを参照してください。IMのインストールフォルダを調べるための、より高度で確実な方法がありますが、これは編集、デバッグ、およびランタイムエラーテストで扱います。 同等のVBスクリプトコードは次のようになります。
|
文字エンコーディング
ImageMagickは文字列をUnicode、より正確にはUTF-8でエンコードします。 これに対し、DOSはコードページを使用して文字をエンコードします(ほとんどの場合8ビット)。 これは、'label' や '-title' を使用する場合など、画像に文字列を書き込む際に問題を引き起こします。非ASCII文字を使用すると、簡単な方法ではうまくいきません。 たとえば、ドイツ語のウムラウト 'ä
'、'ö
'、'ü
' のラベルを作成しようとすると、Linuxでは次のように簡単に使用できます...
|
|
echo
" を使用してこのテキストファイルを作成することもできます。
|
Iconv.exe
" を使用して、必要なときに文字列を変換することです。 SourgeForgeからセットアップファイルをダウンロードし、ファイルを標準ディレクトリC:\Program Files\GnuWin32
にインストールします。 次に、スクリプトでDOSコマンドの出力をテキストファイルにダンプし、そのファイルをUTF-8に変換します。
|
Windows への ImageMagick のインストール
ImageMagickは常に開発されており、新しいバージョンは約1か月ごとにリリースされています。 特にIMが期待どおりにジョブを実行していないと思われる場合は、IMの最新バージョンを使用することを強くお勧めします。 ほとんどの場合、最新バージョンのインストールによって問題が解決します。 現在のバイナリリリースのセットアッププログラムは、https://imagemagick.dokyumento.jp/script/binary-releases.php#windowsにあります。また、Astronomy and Astrophotography BlogからHDRI(浮動小数点品質)とFFT(高速フーリエ変換)対応バージョンのImageMagickをダウンロードすることもできます。 デフォルトでは、IMはC:\Program Files\ImageMagick x.x.x-x
というプログラムディレクトリにインストールされます。ここで、 "x.x.x-x" はバージョン番号を表します。 デフォルトでは、セットアッププログラムは、IMが初めてインストールされたときにPATH環境変数を拡張することを提案します(つまり、「アプリケーションパスをシステムパスに追加する」がチェックされています)。 古いバージョンをアンインストールするのを忘れると、すぐにさまざまなImageMagickバージョンとその対応するPATH拡張機能の素敵なコレクションができてしまいます。そのため、私たちのオフィスでは、IMをC:\Program Files\ImageMagick
にインストールし、新しいバージョンを古いバージョンに上書きインストールし、PATH環境変数は変更しないという習慣を取りました。 何年もの使用で、この手順に問題は見つかりませんでした。 IMのバージョン番号を本当に知りたい場合は、常に "convert -version
" を呼び出すことができ、ダミー耐性のあるスクリプトは、特定の最小バージョン番号に依存している場合にバージョン番号を評価できます。 これについては、セクション "編集、デバッグ、およびランタイムエラーテスト" を参照してください。ImageMagickは、いくつかのレジストリキーをHKEY Local Machine\Software\ImageMagick
に書き込みます。 インストールされている複数のIMバージョンを扱う場合、最も重要なキーはHKEY Local Machine\Software\ImageMagick\Current
であり、ここにはBinPath
と呼ばれるIMのバイナリへのパスもあります。 スクリプトの開始時にこのレジストリエントリを照会し、PATH環境変数に依存せずにプログラムパスを決定できます。 これについては、セクション "編集、デバッグ、およびランタイムエラーテスト" を参照してください。IMのセットアッププログラムでは、*VBscript、Visual Basic、およびWSH用のImageMagickObject OLEコントロールをインストールする*オプションによって、ImageMagickのCOM+オブジェクトをインストールするオプションが提供されています。 このオプションはデフォルトではチェックされておらず、COM+オブジェクトのインストールは、以下で証明するように、VBScriptでIMを使用するための**前提条件ではありません**。 いずれにしても、自分のマシン以外のスクリプトターゲットマシンにCOM+オブジェクトがインストールされていることに依存するべきではありません。PostScriptファイルを扱う場合、ImageMagickはPostScriptおよびPDFファイルを読み取り、使用可能な画像形式に変換するために、別のプログラム "Ghostscript
" に依存します。 つまり、そのようなドキュメントを読み取るには、コンピューターにGhostscriptがインストールされている必要があります。 最新バージョンはSourceForgeからダウンロードできます。 GhostScriptとImageMagickをインストールする順序は関係ありません。 ImageMagickの前にGhostScriptをインストールする必要はなく、ImageMagickはGhostScriptがインストールされていなくても正常に動作します。 PostscriptまたはPDFファイルを処理する場合にのみ必要です。 IMは実行時にGhostscriptの場所を決定し、レジストリからクエリします。特殊事項と落とし穴
Windowsプログラムとしては非常に珍しく、IMは画像を*stdout*に書き込み、*stdin*から読み取ることができるため、パイプを使用して画像処理タスクをカスケードできます。 操作
|
|
|
|
ヘルプの入手
コマンドラインオプションはImageMagickのウェブサイトで詳細に文書化されていますが、実際にそれらをどのように動作させるかを示しているのは、ウェブサイトの使用方法セクションです。このセクションは非常によく構成されており、実行したいタスクに対して問題指向のアプローチを取ることができます。しかし、手っ取り早い方法は、ウェブサイトのそのセクションで、考えているコマンドラインオプションについてGoogle検索することです。複数の画像のモンタージュを実行し、-tileオプションについて調べたい場合は、次のいずれかでGoogle検索を実行できます。すぐに要点がわかります。ただし、これはUNIX / LINUX環境でのアプリケーションを意図したコードが表示されるため、Windowsで適用するにはわずかに調整する必要があることに注意してください。もう1つの非常に役立つ情報源は、IMディスカッションボード、別名Discourse Serverユーザーフォーラムです。これはブラウザのブックマーク/お気に入りに追加する必要があります。メンバーになると質問を投稿することができ、ほとんどの場合、知識のあるユーザーによって迅速に回答されます。補助プログラムと代替手段
はい、それは事実です。ImageMagickよりも他のプログラムの方がうまくできる仕事が確かにあります。一般的に、ImageMagickが提供する一般的な画像操作ではなく、特定の形式を念頭に置いて設計されたものです。- IrfanViewは、おそらくWindowsで最も一般的な画像ビューアであり、基本的な画像操作も可能です。
- Adobe PhotoshopやGimpのようなGUIプログラムは、直接編集や複雑な画像操作手順のテストに適しています。
- デジタル写真のEXIFヘッダーの操作については、JheadとExifToolはImageMagickよりも多用途です。
- PDFからのJPEGストリームの抽出は、xPDFで行う必要があります。
- ビデオ処理は、VirtualDubで行う方が良いでしょう。できればAviSynthとそのエディタAvsPと組み合わせて使用するのが最適です。
Cygwinの使用
上記のように、ImageMagickはUNIXとLinuxを念頭に置いて設計されているため、最も簡単なアプローチは、WindowsシステムにBashシェルをインストールし、そのシステム用に既に作成されているさまざまなIMスクリプト(たとえば、Fred Weinhausのスクリプト)を実行することです。Cygwinは、開発者が言うように、「Windows向けのLinuxのような環境」を提供します。Linuxシェルで通常使用可能なすべてのツールで構成されています。CygwinのBashシェルでFred Weinhausのbashスクリプトをいくつかテストし、完全に機能することを確認しました。Cygwinウェブサイトのルートページの下部に、今すぐインストールまたは更新!というラベルのリンクがあります。これにより、Setup.exeという名前のインストールスタブがダウンロードされます。このプログラムを開始すると、サイトミラーのリストが表示されます。それらの1つを選択すると、ルーチンはインストールするツールのツリービューを提供します。標準の選択は私には妥当なようですので、そのまま続行しても構いません。インストールルーチンは、必要なパッケージをダウンロードし、コンピューターにCygwinをインストールします。![]() ![]() |
インストール時に、デフォルトでは有効になっていない「bc 」パッケージを含めるようにしてください。Cygwinインストールパネルからオプションとしてインストールできます。これは浮動小数点演算ユーティリティであり、Fred Weinhausで使用されているようなIMスクリプトでは不可欠です。 |
- 現在のディレクトリは、DOSとほぼ同様に
CD
コマンドで変更します。ただし、バックスラッシュ( "\ ")はフォワードスラッシュ( "/")に置き換える必要があります。ドライブもDOSと同様にCD
を介して変更されます。そのため、CD w:
はドライブw:に切り替わります。通常のUnix環境とは異なり、パス名は大文字と小文字が区別されません。ウムラウトなどの特殊文字を使用できます。一部のコマンドでは、コロンを避けて、特別な構文でドライブ名を渡す必要があります。たとえば、/cygdrive/w/test
です。 - CywinはWindowsのPATH環境変数を読み取り、それに応じて独自のPATHを設定します。Bashシェルに
echo $PATH
と入力することで確認できます。注:Windowsとは異なり、環境変数の名前は大文字と小文字が区別されるため、PATHを参照する場合は大文字を使用する必要があります。 - Windowsとは異なり、現在のディレクトリはデフォルトでは検索パスに含まれていません!たとえば、シェルスクリプト "autolevel1" が
W:\scripts
にある場合、シェルスクリプトを呼び出すときにそのディレクトリに切り替えるだけでは不十分です。スクリプトの先頭に、少なくとも最小限のディレクトリの場所を追加する必要があります。例:./autolevel1
(現在のディレクトリにあるスクリプトの場合)。または、スクリプトの完全パス。例:/cygdrive/w/scripts
。 - 代わりに、
PATH=$PATH:/cygdrive/w/scripts
を使用して、そのスクリプトディレクトリを検索パスに明示的に追加することもできます。コロンはパス区切り文字として使用されるため、w:/scripts
の代わりに/cygdrive/w/scripts
などの特別な命名法を使用する必要があります。
DOSシェルとバッチファイルの使用
スクリプトの変換: UNIX シェルから Windows DOS へ
DOSコマンドシェル(cmd.exe
を使用)から直接IMコマンドを呼び出す場合は、IMの例サイトに提示されているスクリプト(このセクションに由来しない場合)を変更する必要があります。提供されているほとんどの例(他のセクション)は、一般にUNIXまたはLINUXコマンドシェルで実行することを目的としているためです。DOSコマンドシェルから実行するには、次の変更を行う必要があります。- ほとんどの場合、コマンドの引数が正しいままであるように、単一引用符 '
'
' の代わりに二重引用符 '"
' を使用する必要があります。-draw
演算子などの引用符内の引用符に注意してください。DOSの二重引用符で囲まれた引数内で単一引用符を使用できます。これらはスクリプトによって処理されるのではなく、IMに渡されて処理されるためです。 - 表示されている例の行の末尾にあるバックスラッシュ '
\
' は、「行の継続」を表し、次の行を同じコマンドラインシーケンスに追加します。DOSバッチファイルで行継続を示すには、 '^
' 文字に置き換えます。DOSの場合、次の行もスペースで始める必要がありますが、これはかなり標準的な方法なので、それほど問題にはなりません。すべての行を1行に追加して、これらのバックスラッシュを削除することもできますが、これにより編集と後でコマンドを読み取ることが非常に難しくなります。そのため、この方法は推奨されません。 - 二重引用符で囲まれていないすべての予約済みシェル文字は、リテラルな意味で使用される場合(つまり、通常の目的を果たしていない場合)、 '
^
' (キャレットまたは曲折アクセント記号)でエスケープする必要があります。これらの予約済みシェル文字は、 '&
'、 '|
'、 '(
'、 ')
'、 '<
'、 '>
'、 '^
' です。これは特に次のことを意味します。- 特殊文字 '
>
' (サイズ変更ジオメトリに使用)は、 '^
' を使用してエスケープする必要があります。たとえば、 "-resize 100x100^>
" - 同様に、「内部フィットサイズ変更」フラグ '
^
' は、 '^^
' になるように2倍にする必要があります。
- 特殊文字 '
- UNIXシェルエスケープバックスラッシュ '
\
' は、括弧 '()
' や感嘆符 '!
' をエスケープする必要はありません。 - それ以外の場合は、UNIXシェルエスケープバックスラッシュ '
\
' を、 '<
' や '>
' などのエスケープ文字が使用されている場合は、曲折アクセント記号 '^
' 文字に置き換える必要があります。
たとえば、 "-resize 100x100\>
" は "-resize 100x100^>
" になります。 - DOSバッチファイルでは、パーセント '
%
' 文字にも特別な意味があります。コマンドラインパラメータを参照するためです。たとえば、%1, %2, ...
です(UNIXシェルでは、 '$' 記号が同じ一般的な意味で使用されます)。DOSバッチファイルでは、単一のパーセント記号( "FOR
コマンド" に表示される場合)は '%%
' に2倍にする必要があります。ImageMagick自体は、一般に、パーセント記号が存在するかどうかのみを確認し、複数指定されているかどうかは気にしません。そのため、テキストラベルまたはコメント文字列の一部でない限り、すべてのパーセント記号を2倍にしても、一般的に害はありません。 - Windowsのファイル名にはスペース文字を含めることができることに注意してください。スペースはUNIXでも使用できますがあまり一般的ではありません。スペースが含まれている可能性のあるファイル名は、二重引用符
"file name.jpg"
または"file name".jpg
で囲む必要があります。ドラッグアンドドロップまたはSendToを介してコマンドラインパラメータとしてスクリプトまたはバッチファイルに渡されるファイル名は、スペース文字が含まれていない場合は引用符なしで、スペース文字が含まれている場合は引用符付きでスクリプトに渡されるため、特別な注意が必要です。 - UNIXシェルスクリプトのコメントは、行内の任意の場所にある引用符で囲まれていない '
#
' で始まり、行の末尾まで続きます。色の設定(赤色の場合は "#FF0000
" など)は、多くの場合、この特別な意味を削除するために引用符で囲まれます。この引用符はDOSでは必要ありませんが、二重引用符 '"
' で囲んでも問題なく、そのままにしておく必要があります。DOSでは、コメントは 'REM
'、 '@REM
'、または '::
' プレフィックスを使用して行の先頭にのみ表示できます。ただし、それらも行の末尾まで続きます。どのコメント方法を使用するかは、あなた次第です。ただし、バッチファイルでは常に適切なコメントを作成することをお勧めします。これにより、数か月または数年後にスクリプトに戻ったときに、各ステップでコマンドが何を実行しようとしているかがわかります。他の人が理解するのもずっと簡単になります。すべてのスクリプトは、スクリプトの機能と使用方法を説明する、より大きなコメントで始める必要があります。これは単なる良いプログラミング慣行です。 - DOSバッチファイルを実行すると、個々のコマンドがデフォルトでエコーされます。つまり、コマンドは出力DOSボックスに表示されます。UNIXでは、代わりに特別なコマンドまたはオプションを追加して、この方法で実行されているコマンドを出力する必要があります。この「エコー」出力をオフにするには、スクリプトを "
@ECHO OFF
" で開始します。UNIXシェルスクリプトの特別な開始コメント "#!/path/to/shell
" は、DOSバッチファイルには必要ありません。そのため、この行はDOSバッチファイルの "@ECHO OFF
" コマンドに置き換えることができます。
|
|
cim.txt
は、次のようになります(コメントが削除されている場合)。
|
cim.txt
を、変換するLinuxシェルスクリプトと同じフォルダーに配置した場合、変換は次のように呼び出します。
%programfiles%\GnuWin32\bin\SED -f cim.txt linux.scr > windows.bat |
SET SP=%programfiles%\GnuWin32\bin %SP%\SED -f %SP%\cim.txt "%~1"> "%~dpn1.bat" |
バッチファイルでのファイル名処理
上記のように、IMは画像ファイルに一連の標準的な処理手順を適用する場合に特に便利です。このような場合、ファイル名はドラッグ&ドロップまたは送信先に渡すことにより、コマンドラインパラメータとしてスクリプトに渡されます。これらの手法を使用すると、DOSバッチファイルに渡されるファイル名は、完全修飾ファイル名、つまりドライブ名とディレクトリパスを含むファイル名になります。ファイルを次のバッチファイルにドロップすることで、これをテストできます。
|
|
|
%~1 | %1を展開し、周囲の引用符(")を削除します。 |
%~f1 | %1を完全修飾パス名に展開します。 |
%~d1 | %1をドライブ文字のみに展開します。 |
%~p1 | %1をパスだけに展開します。 |
%~n1 | %1をファイル名だけに展開します。 |
%~x1 | %1をファイル拡張子だけに展開します。 |
|
複数ファイルのバッチ処理
FOR ループ
DOSの`FOR`コマンドは、UNIXと同様に一連のファイルを処理するために使用できます。カレントディレクトリにあるすべてのJPEGファイルを50%縮小するには、DOSボックスに次の行を入力します。
|
|
|
- ドライブ名(d:など)を指定してドライブを変更します。
- ファイルのフォルダをカレントディレクトリにします。
- `small`という名前のサブディレクトリを作成します。
- すべてのJPEGファイルを50%縮小し、これらの縮小バージョンを新しいサブディレクトリに配置します。
|
@ECHO OFF :: Lighten darker areas of all images in a directory %~d1 CD "%~p1" FOR %%a in (*.jpg) DO ( ECHO Processing file: "%%~nxa" magick %%a -blur 30 -negate %%a.miff magick composite %%a.miff %%a -compose overlay "%%~dpn1_light"%%~xa DEL %%a.miff ) PAUSE |
%~d1 CD %~p1 MD small FOR %%a in (*.jpg) DO CALL "%~dp0process" "%%~fa" |
magick %%1 -blur 30 -negate %%1.miff magick composite %%1.miff %%1 -compose overlay "%%~dpn1_light"%%~x1 DEL %%1.miff |
ECHO magick %%1 -blur 30 -negate %%1.miff >%~dp0process.bat ECHO composite %%1.miff %%1 -compose overlay "%%~dpn1_light"%%~x1 >>%~dp0process.bat ECHO DEL %%1.miff >>%~dp0process.bat %~d1 CD %~p1 MD small FOR %%a in (*.jpg) DO CALL "%~dp0process" "%%~fa" DEL %~dp0process.bat |
(サブ)ディレクトリツリーのバッチ処理
(サブ)ディレクトリツリー内のすべてのファイルを処理するには、いくつかの手法があります。最も簡単な方法は、`FOR`ステートメントで`/R`フラグを使用して、カレントディレクトリ以下のすべてのサブディレクトリにあるすべてのファイルをループすることです。サブディレクトリツリー内のすべてのTIFFファイルをJPEGに変換するには、次のように入力します。
|
DEL IDX_????.JPG SET COUNT=0 FOR /F "delims=" %%a in ('DIR /S /B /AD ^|FIND /I "Porsche" ^|SORT') DO CALL c.bat "%%a" DEL title.txt |
CHCP 1252 DIR %1\*.jpg>nul || GOTO :EOF :: Generate IDX filename SET /A COUNT+=1 SET TFILE=000%COUNT% SET TFILE=IDX_%TFILE:~-4%.jpg :: Generate title without bracketing quotes ECHO %~1>temp.txt "C:\Program Files\Gnuwin32\bin\iconv.exe" -f ISO-8859-1 -t UTF-8 temp.txt>title.txt montage -geometry 210x140+0+5 -tile 6x -title @title.txt %1\*.jpg -quality 30%% %TFILE% jhead -cl %1 %TFILE% |
SETLOCAL EnableDelayedExpansion SET ICONV="%PROGRAMFILES%\Gnuwin32\bin\iconv.exe" -f ISO-8859-1 -t UTF-8 CHCP 1252 DEL IDX_????.JPG SET COUNT=0 FOR /F "delims=" %%a in ('DIR /S /B /AD ^|FIND /I "Porsche" ^|SORT') DO ( DIR "%%a\*.jpg">nul IF !ERRORLEVEL!==0 ( SET /A COUNT+=1 SET TFILE=000!COUNT! SET TFILE=IDX_!TFILE:~-4!.jpg ECHO %%a >temp.txt %ICONV% temp.txt>title.txt montage -geometry 210x140+0+5 -tile 6x -title @title.txt "%%a\*.jpg" -quality 30%% !TFILE! jhead -cl %%a !TFILE! ) ) DEL temp.txt DEL title.txt |
- **遅延展開**を有効にし、`FOR`ループ内で使用される環境変数を、パーセント記号ではなく感嘆符で囲むことで参照する必要があります.
- コマンドプロセッサをリセットする`GOTO`ステートメントを回避する必要があります.
FOR
ループ内の環境変数は実行時に評価され**ません**。代わりに、括弧内に指定されたリストを使用してコードが前処理されます。そのため、FOR
ループ内の %COUNT%
への参照は、常に同じ値を返します。環境変数の実行時評価を有効にするには、遅延展開をオンにする必要があります。これは、コマンドプロセッサを cmd /V:on
で呼び出すか、次の REG ファイルを使用してレジストリで一般的にオンにすることで実行できます。
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor] "DelayedExpansion"="1" [HKEY_CURRENT_USER\Software\Microsoft\Command Processor] "DelayedExpansion"="1" |
SETLOCAL EnableDelayedExpansion
を使用してこのオプションを設定することです。これにより、環境変数の変更がコマンドプロセッサの現在のバージョンに限定され、おそらくそれが望ましいでしょう。ループ内で環境変数の実行時の値を参照するには、パーセント記号の代わりに感嘆符を使用する必要があります。 FOR
ループ内で GOTO
ステートメントを使用すると、非常に微妙なエラーが発生する可能性があるため、避けるべきです。ただし、私たちのバッチでは、モンタージュコードを含むコードブロックを囲む IF
ステートメントでジャンプを簡単に置き換えることができます。 任意の数のファイルのバッチ処理
DOS バッチファイルでは、%1
から %9
まで、9 つのコマンドラインパラメータのみを直接アドレス指定できます。以前のバージョンの Windows では、この制限を回避するには SHIFT
コマンドを使用するしかありませんでした。これは、コマンドラインパラメータの循環シフトを引き起こしました。新しいバージョンでは、コマンドラインパラメータは For ループで処理できます。
FOR %%i in (%*) DO ... |
@ECHO OFF SETLOCAL EnableDelayedExpansion %~d1 CD "%~p1" DEL Files.txt 2>nul: DEL FSorted.txt 2>nul: FOR %%I in (%*) DO ECHO %%~nxI>>files.txt FOR /F "delims=" %%A in ('TYPE files.txt ^| Sort') Do ( ECHO %%A>>fsorted.txt ) SET MONTAGE=montage -tile 3x FOR /F "delims=" %%A in (FSorted.txt) Do ( SET MONTAGE=!MONTAGE! %%A ) SET MONTAGE=%MONTAGE% result%~x1 %MONTAGE% DEL Files.txt DEL FSorted.txt |
files.txt
にダンプします。ファイルがアルファベット順に選択された場合でも、ファイル名がスクリプトに渡されたときにこの順序が維持されるとは限りません。そのため、2 番目の作業手順でファイルを順序付け、fsorted.txt
にダンプします。このファイルに基づいて、別の For ループで Montage コマンドラインを構築します。Montage 出力ファイルは、最初の入力ファイルと同じ拡張子(%~x1
)を使用します。(すべてのファイルが同じ拡張子を共有していると仮定します。)最終的な Montage コマンドは、環境変数を評価することによってのみ呼び出されることに注意してください。つまり、%MONTAGE%
です。 で述べたように、Windows XP では、長い(完全な)ファイル名を持つ大量のファイルを渡すと、ShellExecute のパラメータリストが 2048 文字に制限されているため、問題が発生する可能性があります。このエラーは、バッチファイルに制御が渡される**前**に発生するため、バッチファイルでは処理できません。スクリプトベースの解決策としては、1 つのファイルだけがバッチに渡されたときに、ディレクトリ内のすべての画像ファイルを処理する方法があります。
%~d1 & IF EXIST %1\* (CD %1) ELSE CD %~p1 IF "%2"=="" ( SET PATTERN=*.jpg ) ELSE ( SET PATTERN=%* ) FOR %%v IN (%PATTERN%) DO (...) |
- フォルダ名がスクリプトに渡された場合は CD %1
- ファイル名がスクリプトに渡された場合は CD %p1。
ImageMagick からの情報取得
IM コマンド出力の再利用
最近のバージョンの Windows では、FOR
ステートメントがはるかに強力になっています。 DOS "For" コマンドヘルプ を参照してください。"/F
" オプションを使用すると、置換変数の入力をファイル、文字列、または別のコマンドやプログラムの出力から読み取ることができます。後者は IM で特に役立ちます。IM のオーバーレイメソッドが実際にはどのようなものであるかを知るには、次のバッチファイルを使用できます。
|
![]() Src |
![]() Dst |
![]() |
![]() Multiply |
![]() Screen |
![]() Overlay |
Convert -list compose
は、使用可能なオプションのリストを、それぞれ 1 つの出力行に配置して提供します。括弧内でコマンドを参照するときは、単一引用符を使用する必要があることに注意してください。"/F
" オプションを使用すると、FOR
コマンドはこれらの出力行をそれぞれ処理し、DO
によって実行されるコマンドに渡します。その結果、2 つのグラデーション画像は、IM が認識するすべてのオーバーレイメソッドを適用して重ね合わされます。出力ファイルには、オーバーレイメソッドに対応する名前が付けられます。 次の例では、IM が提供する色空間を示します。上記ののと同じグラデーション手法を使用して、色空間の 3 つの座標によって張られる立方体のサーフェスを生成します。
|
![]() colorspace RGB |
![]() colorspace sRGB |
%1
" として受け取ります。次に、立方体の 3 つの側面を生成し、せん断してマウントし、点(0,0,0)が六角形の中心に位置する等角図を取得します。最終的な画像は、色空間(つまり "%1
")にちなんで名付けられ、PNG として保存されます。次に、このバッチファイル("cspace.bat
" として保存)を、色空間の名前を提供する別のバッチファイルから呼び出します。
|
-list
オプションの出力をフィルタリングすることもできます。
magick -list colorspace | FIND "RGB" >>clist.txt FOR /F %%A in (clist.txt) DO CALL cspace %%A DEL clist.txt |
clist.txt
に書き込みます。このファイルは、FOR /F
コマンドの入力として使用されます。一時ファイルを使用せずに、これを 1 回の実行で行うこともできます。
|
|
" はエスケープする必要があります。これは、二重引用符で囲まれておらず(FOR
ステートメントに必要な単一引用符でのみ囲まれている)、(少なくとも上記のコマンドラインでは)通常の感覚では意図されていないためです。 単一行出力の処理
この手法は、単一行出力にも有効に適用できます。たとえば、Fred Weinhaus のウェブサイト で説明されている手法により、画像の平均輝度を量子範囲の中央(つまり、色深度が 8 ビットの場合は 127)にほぼ設定する自動ガンマ補正を適用できます。
|
%1
" として渡されます。これは、ドラッグ&ドロップまたは SendTo によって行われる可能性が高くなります。IM の Identify コマンドの出力は、ガンマ値を提供します。これにより、画像の平均輝度がダイナミックレンジの中央に設定されます。この値は、FX 形式の式 を使用して計算されます。Identify コマンドの単一行出力は "%%a
" 変数に保存され、ガンマ演算子 の引数として Convert コマンドに渡されます。![]() ![]() |
FOR コマンドは、行継続に関しては非常に敏感なようです。使用する場合は、次の行をスペースで開始しないようにしてください。 |
![]() ![]() |
この自動ガンマ補正の方法は、現在 "-auto-gamma " を使用して IM に組み込まれており、IM v6.5.5-1 に追加されました。しかし、後のコマンド引数で使用するためにコマンド出力を再利用する手法を示しています。 |
FOR
手法を使用して、写真に埋め込まれた EXIF 情報を読み取り、画像の左上隅に書き込むことができます。
|
![]() ![]() |
写真は通常 JPEG 形式で保存されます。JPEG 画像の読み取りと再保存を行うと、JPEG ロス圧縮 により画像がわずかに劣化するため、JPEG に戻して保存することはお勧めしません。 |
%1
" として参照されます。Identify コマンドは、JPEG ファイル内の EXIF 情報から写真が撮影された日時を読み取ります。FOR
コマンドは、この出力を Convert に渡し、それに対応して写真の左上隅に注釈を付けます。EXIF の日付と時刻の情報は "yyyy:mm:dd hh:mm:ss"(例:"2006:12:26 00:22:38")としてフォーマットされます。したがって、日付と時刻はスペース文字で区切られます。デフォルトでは、FOR
ステートメントは、タブ文字とスペース文字を標準の区切り文字として、各行の最初のトークン(「単語」)のみを見つけます。したがって、上記の例では、標準処理では日付のみが処理され、時刻は処理されません。"tokens=1,2
" オプションを使用すると、両方のトークンに関心があることを宣言します。これらのトークンには、IE のように連続した名前が付けられます。"%x, %y
"。ただし、次のコードを使用して、日付のやや型破りなフォーマットを変更できます。
|
:
')を追加の区切り文字として定義したため、日付は 3 つのトークン "%i
"、"%j
"、"%k
" に分割されます。次に見つかった区切り文字は、日付と時刻を区切るスペース文字です。アスタリスク("*")を使用して、行の残りを 4 番目のトークン "%l
" に格納するように要求しています。これで、日付を好きなようにフォーマットできます。上記の例では、英米表記の "mm/dd/yyyy" を選択しました。 単一コマンドからの複数値の設定
1 つの ImageMagick コマンドから複数の値を設定する手法は、コマンドにデータをフォーマットさせて、複数の変数を設定できるようにすることです。
|
Width
' と 'Height
' の両方が設定されます。 計算の実行
DOS コマンドインタープリタは、計算に関しては貧弱です。単純な整数演算を実行するために使用できます。しかし、より複雑な浮動小数点数学を実行するには、IM の FX 形式の式、またはサードパーティの DOS 電卓プログラムにアクセスできます。IM の FX 式の使用
IMのFXフォーマット式は、浮動小数点演算に使用でき、前述の単一行出力の処理セクションの最初の例で示したように、その演算をより大きなフォーマット済み文字列に追加できます。SET
コマンドを使用することにより、結果は環境変数に格納され、バッチファイル内で後で利用できます。簡単な例として、上記の例の日付時刻文字列のフォントサイズを写真の寸法に合わせて調整してみましょう。
|
%[fx:min(w,h)]
" で評価し、この値の5%を取得して環境変数PSIZEに格納します。この値は、次のステートメント(%psize%
)で参照され、日付時刻情報のフォントサイズを設定します。そしてここでは、-15°から+15°までの整数の乱数角度を計算して、回転したサムネイル画像を作成します。
|
SET コマンドの使用
SET
コマンドは、"/A
"オプションが呼び出されると、いくつかの簡単な整数演算と基本的な文字列操作を実行できます。次の例では、SET
コマンドを使用して、日付時刻文字列の幅を大まかに計算します。
|
%mean%
)に対応するように選択します。平均色の強度が50%未満の場合、文字列は白になり、それ以外の場合は黒になります。この例では、IF
ステートメントも使用しています。 ELSE
部分は同じ行に配置する必要があり、最初のコマンドは括弧で囲む必要があることに注意してください。 その他の外部計算機の使用
代わりに、EVALなどの浮動小数点演算を提供するDOSプログラムを使用できます。このファイルをIMプログラムディレクトリまたはWindowsシステムディレクトリに配置すると、任意のDOSシェルウィンドウで浮動小数点計算を実行できます。EVAL
プログラム、FOR
コマンド、および環境変数を使用することで、上記のカラーキューブの例をより柔軟にし、さまざまな計算をより透過的にすることができます。
|
編集、デバッグ、および実行時エラーテスト
原則として、DOSバッチファイルは、Windowsのメモ帳でも、任意のエディターで記述できます。ただし、DOSバッチファイルの構文強調表示を備えたエディターを使用する必要があります。個人的にはNotepad++が最適なツールだと思いますが、エディターの話は人々を不快にする傾向があります。ですから、他のエディターでも構いません。私の知る限り、市場には無料のバッチファイルIDE(統合開発環境)はありません。これはオペレーティングシステムに付属しているべきものだと思うかもしれませんが、そうではありませんでした。これまでのところ、私はすべてのバッチファイルをNotepad++で記述しましたが、定期的にバッチファイルを記述する人にとっては、Running StepsバッチIDEが役立つかもしれません。これはシェアウェアで、約80ドルです。DOSコマンドの包括的な説明は、http://www.computerhope.com/msdos.htmにあります。DOSバッチ言語自体と同様に、バッチファイルのデバッグはかなり奇妙な作業です。まずはDOSボックスでバッチファイルをテストします。ドラッグアンドドロップまたは送信先をテストする場合、バッチジョブの完了後にDOSボックスが開いたままになるように、バッチファイルをPAUSE
ステートメントで終了することをお勧めします。ランタイムエラーメッセージを考慮すると、一般的なアプローチはDOSのERRORLEVEL
をチェックし、ECHO
コマンドによって生成された対応するエラーメッセージにジャンプすることです。最も可能性の高いエラーの原因の1つは、Convertプログラムがスクリプトを実行しているマシンで正しく見つからないことです。そのため、バッチスクリプトを他のユーザーと共有する場合は、まずConvertにアクセスできるかどうかを確認する必要があります。
@ECHO OFF magick -version 1>nul: 2>nul: IF NOT %errorlevel%==0 GOTO NoMagick: magick ... GOTO :EOF ... :NoMagick ECHO ImageMagick (convert.exe) not found. PAUSE |
1>nul:
(または単に>nul:
)で、エラーメッセージを2>nul:
で抑制します。つまり、stdout
とstderr
をnul:
にリダイレクトします。 IMのConvertの呼び出しが失敗した場合、代わりにシステムプログラムConvertが呼び出されます。これは-version
オプションを処理できず、ERRORLEVEL変数を設定します。 Convertが見つからない理由を特定し、問題の解決を試みることができます。IMのプログラムパスが環境変数PATHの一部であるかどうかを判断できます。
@ECHO OFF PATH | FIND /I "ImageMagick" IF NOT %errorlevel%==0 GOTO NoPath: ... :NoPath ... |
@ECHO OFF FOR /F "tokens=1,2,*" %%A in ^ ('reg query "HKCM\Software\ImageMagick\Current" ^| FIND "BinPath"') DO ^ SET MPATH=%%C IF [%MPATH%]==[] GOTO NoMagick: "MPATH\convert.exe" ... ... :NoMagick ... |
Current
を照会し、BinPathエントリを検索します。出力の決定的な行は次のとおりです。LibPath REG_SZ C:\Program Files\ImageMagick
このテキスト行の「単語」は、タブ(Windows XPの場合)または複数の空白(Windows Vistaの場合)で区切られています。これらは、For /F
で使用される標準の区切り文字です。 3番目の「単語」(%% C)は私たちが探しているものであり、環境変数MPATHに格納します。これは、後でスクリプトでmagickを呼び出すときに参照できます。スクリプトでは、特定の最小バージョンのImageMagickがインストールされている必要があります。たとえば、パースペクティブ歪みメソッドは、バージョン6.3.5-9(2007年9月)で最初に実装されました。したがって、スクリプトがパースペクティブ補正を扱う場合は、インストールされているIMのバージョンがそれよりも新しいかどうかをテストする必要があります。
@ECHO OFF SETLOCAL EnableDelayedExpansion SET MINVERSION=7.5.3-0 FOR /F "tokens=1,2,3" %%a in ('magick -version ^|FIND "Version"') DO SET VERSION=%%c IF %VERSION% LSS %MINVERSION% GOTO GetNewVersion: Goto :EOF :GetNewVersion ECHO This Script requires et least ImageMagick version %MINVERSION%. ECHO Yours is %VERSION%. PAUSE Goto :EOF |
SETLOCAL
は、環境変数の変更を現在のスクリプトに制限するため、副作用を befürchtenする必要はありません。オプションEnableDelayedExpansion
はここでは実際には必要ありませんが、SETLOCAL
を使用するたびにそのオプションを使用することをお勧めします。次に、必要な最小バージョンを環境変数MINVERSIONに格納します。 3行目では、 '-version'オプションを指定してConvertを呼び出し、^|FIND "Version"
を介して出力から最初の行を抽出し、その行から3番目の単語を取得して、環境変数VERSIONに格納します。次に、このバージョンを4行目の最小必須バージョンと比較します。 実行時間の最適化
実行時間を測定するには、%TEMP%
環境変数の内容を表示します。次のスクリプトは、(大きな)画像ファイル、たとえばデジタル写真の平均輝度を計算するさまざまな方法をテストします。
IF "%1"=="" GOTO :EOF ECHO %TIME% Identify -verbose %1 | FIND "mean" & ECHO %TIME% copy %1 %TEMP%\*.* & ECHO %TIME% Identify -verbose %TEMP%\%1 | FIND "mean" & ECHO %TIME% Convert %TEMP%\%1 -format %%[fx:mean] info: & ECHO %TIME% Convert %TEMP%\%1 -resize 1x1! -format %%[fx:mean] info: & ECHO %TIME% DEL %TEMP%\%1 |
%TIME%
をエコーすることによって、さまざまなアプローチの実行時間が測定されます。アンパサンド&
を使用すると、1行に複数のDOSコマンドを配置でき、ここではコードに必要なスペースを短縮するために使用されます。画像がネットワークドライブにある場合、クライアントコンピュータのメモリへの転送にかなりの実行時間がかかる場合があります。したがって、ファイルは、名前が環境変数%TEMP%
に格納されているローカル一時フォルダーにコピーされます。単純なConvertコマンドは、Identifyの結果をフィルタリングするのと同じくらいの実行時間を要しますが、-resize 1x1!
を介して画像のサイズを1ピクセルに変更すると、結果をあまり変更せずに操作が大幅に高速化されます。後者は時間と分のみを表示しますが、前者は100分の1秒を提供するため、TIME /T
の代わりにECHO %TIME%
を使用していることに注意してください。 UNIXコマンドシェルとは対照的に、相対時間を測定する直接的な方法、つまり基準点を設定し、ステートメントを実行してから、必要な時間を評価する方法はありません。バッチファイル内での相対時間の計算は、バッチファイルが整数演算のみを許可するという事実によって困難になります。 FORコマンドで秒数を抽出し、次にIMのfx演算子を使用して減算を実行することで、60秒のオーバーフローを可能にすることができます。
FOR /F "tokens=1,2,* delims=:" %%a in ("%TIME%") DO SET START=%%c ... some command(s)... FOR /F "tokens=1,2,* delims=:" %%a in ("%TIME%") DO SET STOP=%%c Convert null: -format "%%[fx:(%STOP%-%START%<0.0)?%STOP%-%START%+60.0:%STOP%-%START%]" info: |
for /f "tokens=1-4 delims=:., " %%a in ("%TIME%") do ^ set /a Start100S=1%%a * 360000 + 1%%b * 6000 + 1%%c * 100 + 1%%d - 36610100 |
バッチプログラミングのガイドライン
これらは、バッチファイルのプログラミング時に従うべきルールです。SETLOCAL EnableDelayedExpansion
から始めます。- IMのConvertツールを参照する変数を定義します:
SET IMCONV="%PROGRAMFILES%\ImageMagick"
- 複数のファイルを操作する場合、ファイルを格納するフォルダーを現在のフォルダーにすると、多くの場合、コードが簡素化されます。つまり、
%~d1
を介してドライブに変更しますCD %~p1
を介してフォルダーに変更します
- GnuToolsのiconv.exeを使用して、テキストをUTF-8に変換し、ファイルからテキストを入力します。
- ConvertとMontageは、テキスト出力を*stdout*ではなく*stderr*に書き込むことに注意してください。
- 空白を含むファイル名に起因するエラーが多く発生するため、各バッチでそのようなファイル名が正しく処理されるかどうかを確認してください。
- JEPG品質を設定する場合など、すべてのパーセント記号を2倍にすることを忘れないでください。
- 文字列の特殊文字( "^|"など)をエスケープすることを忘れないでください。
SET /A
によって実行される整数計算は、ゼロで始まる数値を8進数として扱うため、各数値の前に「1」を付けます。
まとめ
上記の例は、シンプルなDOSバッチファイルが、ImageMagickによって提供される可能性と組み合わせることで、驚くほど多用途であることを証明しています。実際、ほとんどすべてのことが、バッチファイルで(多少荒削りな方法ではありますが)実行できます。DOSバッチファイル言語の開発で用いられた独特の思考方法に慣れてしまえば、スクリプトはむしろ短くなることさえあります。それでも、バッチファイル言語に精通していない限り、これらの数行のコードは、おそらく何時間も退屈な実験に費やされたことでしょう。基本的な画像処理タスク以上のことを目指している場合は、より洗練されたスクリプト言語を使用することをお勧めします。コードの開発がよりシンプルで構造化されたものになるからです。Visual Basic Script (VBS)
Microsoft Windows Script Host (WSH) のスクリプト機能は、単純なバッチファイル言語よりも洗練されています。WSHは、さまざまなActive Scripting言語エンジンを利用できるという意味で、言語に依存しません。デフォルトでは、プレーンテキストのJScriptファイル(Java Script)とVBScriptファイル(VisualBasic Script)を解釈して実行します。Windows Script Hostは、Windows 98以降ではデフォルトで配布およびインストールされています(ただし、セキュリティ上の懸念から、ターゲットマシンで無効になっている場合があります)。WSHは、システムオブジェクト、特にファイルシステムをアドレス指定できるCOMインターフェースのセットを公開するオブジェクトモデルを実装しています。ここでは、Windows Script Hostについては詳しく説明しません(他の場所で、おそらくより適切に説明されています)。代わりに、典型的な問題に対処する方法の実用的な例をいくつか示します。例はVisualBasic Scriptで示されていますが、JScriptコードも非常によく似ているため、JScriptがお好みの言語であれば、例をJScriptで書き直すのは簡単です。バッチファイルと同様に、VBScriptは任意のエディタで記述できます。ここでも、Notepad++を推奨のエディタとしてお勧めします。バッチファイルの場合と同様に、MicrosoftはVBScriptの開発をサポートする専用のIDEを提供していません。Microsoft Office 2000から2003に付属していたMicrosoft Script Editorがありましたが、私は試したことがありません。Microsoftは(非常に初歩的な)Microsoft Script Debuggerも提供していますが、これも私自身はあまり経験がありません。 VbsEdit のように、リーズナブルな価格でシェアウェアとして提供されている商用のVBS IDEがいくつかあります。WindowsへのImageMagickのインストールセクションで述べたように、以下では一般的にImageMagickのCOM+インターフェースは使用しません。Convert、Montage、IdentifyなどのIMのツールは、バッチファイルで行うのとほぼ同じように、必要なすべてのオプションとファイル名を使用して、シェルの実行コマンドによって直接実行されます。ただし、コマンド文字列を組み立てるときには、実際のプログラミング言語が提供する機能を利用します。基本的な例: レンズ補正
WSHの使用には多少のオーバーヘッドが発生するため、VBScriptの単純なバッチファイルに対する利点を示すために、開始例はそれほど基本的ではありません。以下では、IMの樽型歪みを使用して、Nikon 995デジタルカメラのレンズ歪みを補正します。補正パラメータは焦点距離に依存し、これは最初に `magick identify` を介して調べられます。Nikon 995レンズの補正には、パラメータ *b*(つまり *a, c* = 0)のみが必要です。これは、焦点距離 *f* から次の式で計算できます。*b* = 0.000005142 *f*³ - 0.000380839 *f*² + 0.009606325 *f* - 0.075316854 この依存関係は、このレンズの樽型歪みパラメータをリストするlensfunデータベースによって発見されました。VBScriptは次のとおりです。
SetLocale(1033) ' US, i.e. decimal point const strConv = "IMCONV" ' name of the IM Convert program const strAdd = "_pt" ' string attached to the filename ' Dim wsh Set wsh = CreateObject("Wscript.Shell") ' ' names of the in- and output files strFileIn = WScript.Arguments(0) Pos = InStrRev(strFileIn,".") strFileOut = Left(strFileIn,Pos - 1) & strAdd & Mid(strFileIn, Pos) ' ' evaluation of the focal length and calculation of parameter b command = "identify -format ""%[EXIF:FocalLength]"" """ & strFileIn & """" Set objExec = wsh.Exec(command) strf = objExec.StdOut.Readline f = eval(strf) b = 0.000005142 * f * f * f -0.000380839 * f * f + 0.009606325 * f -0.075316854 ' Command = strConv & " """ & strFileIn _ & """ -virtual-pixel black -filter point -distort Barrel ""0.0 " _ & b & " 0.0 "" """ & strFileOut & """" wsh.run command,7,true |
- テキスト出力が予期されない場合は、ShellオブジェクトのRunコマンドを介して呼び出します。
- Identifyの場合のように、テキスト出力を評価する必要がある場合は、ShellオブジェクトのExecコマンドを介して呼び出します。
SETLOCAL EnableDelayedExpansion FOR /F %%i in ('identify -format "%%[EXIF:FocalLength]" %1') DO SET FL=%%i FOR /F %%i IN ('Convert null: -format "%%[fx:0.000005142*(%FL%)^3 - 0.000380839 * (%FL%)^2 + 0.009606325 * %FL% - 0.075316854]" info:') DO SET B=%%i Convert %1 -distort barrel "0.0 !B! 0.0" "%~dpn1_pt%~x1" |
複数ファイルの操作
DOSバッチファイルと比較したVBScriptの真の利点の1つは、任意の数のコマンドライン引数を簡単にループできることです。たとえば、Windowsエクスプローラーで複数のファイルを選択し、選択した画像をIMのMontageを介してインデックスプリントに結合できます。基本的なコードは次のとおりです。
Dim wsh Set wsh = CreateObject("Wscript.Shell") ' strInputFiles = "" For EACH Arg IN WScript.Arguments strInputFiles = strInputFiles & " """ & Arg & """" next ' IndexFile= Left(WScript.Arguments(1),InStrRev(WScript.Arguments(1),"\")) & "index.jpg" Command = "montage -geometry 210x140+0+5 -tile 6x " & strInputfiles & " -quality 80% """ & IndexFile & """" wsh.run command, 7, true |
Dim FName() Dim wsh Set wsh = CreateObject("Wscript.Shell") ' NArgs = WScript.Arguments.Count Redim FName(NArgs-1) FOR i = 0 TO NArgs - 1 FName(i) = """" & WScript.Arguments(i) & """" NEXT |
Dim fs, folder Set fs = CreateObject("Scripting.FileSystemObject") If WScript.Arguments.Count <> 1 Then WScript.Quit(1) set Folder = fs.getFolder(fs.GetParentFoldername(WScript.Arguments(0))) FN="" FOR EACH file in folder.files If instr(file,"gif") <> 0 THEN FN = FN & File & vbLF NEXT MsgBox FN |
for i = 0 to NArgs - 1 for j = i + 1 to NArgs - 1 if FName(i) > FName(j) then Temp = FName(i) FName(i) = FName(j) FName(j) = Temp end if next next |
![[clip]](../img_photos/clip.jpg)
テキストファイルの操作
クライアントコンピューターでスクリプトを使用する場合、入力情報は一般にドラッグアンドドロップまたは送信先を介して提供されます。つまり、基本的にスクリプトによって事前定義された方法で処理されるファイル名で構成されます。追加情報は、実行時にユーザーインタラクションによって提供されるか、テキストファイルの形式で提供される必要があります。基本的に、次のオプションがあります。- スクリプトは、追加情報を提供する(場合によってはオプションの)テキストファイルを伴う画像ファイルを、入力として受け入れます。
- スクリプトは、処理対象の画像と必要な追加情報をリストした単一のテキストファイルを、入力として受け入れます。
strTxtFile="ordering.txt" PDir = fs.getParentFolderName(FName(0)) & "\" Wsh.CurrentDirectory = PDir If fs.FileExists(strTxtFile) then Set objFile = fs.OpenTextFile(strTxtFile, 1) bCtrlFile = True NCols = objFile.ReadLine objFile.close else bCtrlFile = False end if |
![[クリップ]](../img_photos/wm.jpg)
パイプ処理
これまで、ShellオブジェクトのRun関数またはExec関数を使用して、IMのコマンドラインツール(Convert、Identify、Montageなど)を直接呼び出していました。ただし、IMのパイプ機能を使用する場合、つまり、前のコマンドの出力を次のコマンドにフィードする場合、コマンド環境を介してコマンドラインツールを呼び出す必要があります。たとえば、上記のスクリプトによって生成されたインデックスプリントの白い境界線をトリミングする場合、コードは次のようになります。
Dim wsh Set wsh = CreateObject("Wscript.Shell") ' strInputFiles = "" For EACH Arg IN WScript.Arguments strInputFiles = strInputFiles & " """ & Arg & """" next ' IndexFile= Left(WScript.Arguments(1),InStrRev(WScript.Arguments(1),"\")) & "index.jpg" Command = "cmd /c montage -geometry 210x140+0+5 -tile 6x " & strInputfiles & " miff:- | magick - -trim """ & IndexFile & """" wsh.run command, 7, true |
VBScript のテストとデバッグ
基本的には、VBScriptを使用してIMのコマンドラインツールの引数リストを作成し、それらを単独で、またはDOSボックス内で実行します。これは、まず第一に、次のことを確認する必要があることを意味します。- コマンドライン自体が期待どおりに動作すること
- コマンドラインがスクリプトによって正しく構築されていること。
- IMのコマンドラインツールに正しくアクセスできること
- ユーザーが期待どおりの選択を行っていること。つまり、複数のファイル(特定のタイプの可能性もある)、ディレクトリ、テキストファイルなど。