Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2017年09月27日] [更新 2017年09月29日] Delphi 一般・その他
   
ImageMagick を使用した画像ファイル形式の変換
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro
ImageMagick-7.0.7-4-portable-Q16-x86.zip
ImageMagick-7.0.7-4-Q16-x86-dll.exe
Ghostscript 9.21 for Windows (32 bit), PascalMagick-0.4.zip

[整理番号 - 652]







Delphi で ImageMagick を使用する


ImageMagick (イメージマジック) は画像の形式変換,加工,編集のためのコマンドライン用ライブラリです.GUI 操作のツールではありません.
その特長の 1 つが非常に多くの形式の画像を扱えることです.2017年09月現在,ImageMagick のサイトの記事によると 200 種類以上となっています.

Delphi から ImageMagick を利用する方法は主に 2 つの方法があります.
1 つはコマンドライン専用の portable 版 ImageMagick をダウンロードして適当なフォルダに解凍する方法です.portable 版はインストールの必要はありませんが,全ての機能を利用するには解凍先のフォルダにパスを設定する必要があります.

もう 1 は DLL 版 ImageMagick をインストールする方法です.DLL 版では PascalMagick が提供しているユニットを使用して ImageMagick の関数類が利用できます. また,インストールの時に,インストール先のフォルダに自動的にパスが設定されます.
DLL 版には portable 版の機能であるコマンドラインツールも含まれています.



ImageMagick には IMDisplay.exe という画像ピューワが付属しています.ImageMagick で扱える全ての画像形式というわけにはいきませんが,いくつかの形式の画像を読み込んで表示できます.
また,ImageMagick で扱える全ての機能ではありませんが,画像の加工や編集も可能です.読み込んだ画像を別の形式の画像にして保存できます.



図1
ImageMagick に付属の画像ピューワ

ImageMagick サイトの参考記事へのリンク
ImageMagick サイトのトップページ
http://www.imagemagick.org/script/index.php
ImageMagick の Windows での使用
http://www.imagemagick.org/Usage/windows/
ImageMagick コマンドライン (CLI) オプションのマニュアル
http://www.imagemagick.org/script/command-line-options.php
ImageMagick の使用例 (コマンドライン用のコード)
https://www.imagemagick.org/Usage/
デジタルカメラの写真 (JPEG 画像) の操作関係
https://www.imagemagick.org/Usage/photos/
フーリエ変換関係のサンプル
http://www.imagemagick.org/Usage/fourier/


[備考 1]
ImageMagick はコマンドラインのツールですが,GUI 操作で画像の加工や編集の機能を持つフリーのツールとしては IrfanView (イルファンビュー・イーファンビュー),GIMP (ジンプ・ギンプ) 等があります.IrfanView, GIMP 共にコマンドラインからの画像操作も可能です. アイコン等の画像の編集用としては,以下のような専用のツールがあります.

[備考 2]
当サイトでも PerlMagick という Perl 用の ImageMagick を利用しています.掲示板に掲載する画像のアンチエイリアス処理に使用しています.
この PerlMagick はレンタルサーバが提供している機能です.


[備考 3]
Linux 系の OS では ImageMagick を使用するライブラリが多くあります.そのため,ImageMagick がプリインストールされているのが一般的です.





ImageMagick のコマンドラインツールのダウンロード


ImageMagick のコマンドラインツールは以下からダウンロードできます.

筆者のテスト環境は 64 ビットの Windows 7 ですが,32 ビットの EXE を作成するので 32 ビット用である x86 の表記があるファイルをダウンロードしました.コマンドラインツールは EXE ファイルで提供されています.したがって,64 ビット用のでも利用できます.32 ビットの EXE からは 64 ビットの EXE も実行できます.逆に,64 ビットの EXE からも 32 ビットの EXE は実行できます.ただし,32 ビット版の Windows では 64 ビットの EXE は実行できません.
ダウンロードしたら適当なフォルダに解凍します.



ダウンロードファイル名の portable がコマンドラインツールのファイルです.Q16 は 64 ビットの色数を扱えることを意味しています.Q8 は 32 ビットの色数まで扱えます.x86 は 32 ビット,x64 は 64 ビットの EXE となっています.



図2
ImageMagick のコマンドラインツールのダウンロード
  • ダウンロードしたら適当なフォルダに解凍する




ImageMagick のコマンドツールで PNG 画像を GIF 画像に変換


ImageMagick のコマンドラインツールを使用して,PNG 形式の画像を GIF 画像に変換する例です.コマンドラインのオプションで画像のサイズを変更しています.
テストに使用している logo.png は,ImageMagick に添付されている ImageMagick のロゴ画像です.



図3
ImageMagick のロゴ画像
  • 実際のサイズは 2135 x 2048
  • 下のコードでは幅を 300 にして GIF 画像として保存する
  • 縦のサイズは縦横比を保持するので 288 となる

リスト1
ImageMagick のコマンドラインツールで PNG 画像を GIF 画像に変換
uses
  ShellAPI;

{$R *.dfm}

//=============================================================================
//  PNG画像ファイルをGIF画像ファイルに変換
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LCmdExePath : string;
  LCmdLine    : string;
begin
  //使用するImageMagickのコマンドラインツールのパス
  LCmdExePath := ExpandFileName('..\magick.exe');

  //コマンドパラメータ
  LCmdLine := ExpandFileName('logo.png')
            + ' -resize 300'
            + ' ' + ExpandFileName('logo.gif');

  ShellExecute(0, '', PChar(LCmdExePath), PChar(LCmdLine), nil, SW_HIDE);
end;




ImageMagick で PDF 文書を扱うには Ghostscript が必要


ImageMagick では PDF も扱えますが,Ghostscript (ゴーストスクリプト) が必要です.Ghostscript は以下のリンクからダウンロードできます.

筆者のテスト環境は 64 ビットの Windows 7 ですが,32 ビットの EXE を作成するので 32 ビット版の Ghostscript をダウンロードしてインストールしました.



図4
Ghostscript のダウンロード
  • ダウンロードしたら EXE を起動してインストールする




ImageMagick のコマンドラインツールで PDF を JPEG 画像に変換


Ghostscript をインストールして PDF 文書を扱う準備できました.実際に PDF 文書を JPEG 画像ファイルにして保存するサンプルです.変換の際に解像度を指定しています.

最初のボタンクリックでは,PDF の全てのページを JPEG 画像に変換します.JPEG 画像はページ数分作成されます.ページ数が多いとかなり時間がかかります.
次のボタンクリックでは,ページ範囲を指定して JPEG 画像に変換します.



リスト2
ImageMagick のコマンドラインツールで PDF を JPEG 画像に変換する
uses
  ShellAPI;

{$R *.dfm}

//=============================================================================
//  PDF文書ファイルをJPEG画像ファイルに変換
//  全ページを変換する場合
//  ページ数が多いと非常に時間がかかる
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LCmdExePath : string;
  LCmdLine    : string;
begin
  //使用するImageMagickのコマンドラインツールのパス
  LCmdExePath := ExpandFileName('..\magick.exe');

  //コマンドパラメータ
  LCmdLine := ' -density 96'
            + ' ' + ExpandFileName('テスト.pdf')
            + ' ' + ExpandFileName('TestAcro.jpg');

  ShellExecute(0, '', PChar(LCmdExePath), PChar(LCmdLine), nil, SW_HIDE);
end;

//=============================================================================
//  PDF文書ファイルをJPEG画像ファイルに変換
//  ページ範囲を指定して変換する場合
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LCmdExePath : string;
  LCmdLine    : string;
begin
  //使用するImageMagickのコマンドラインツールのパス
  LCmdExePath := ExpandFileName('..\magick.exe');

  //コマンドパラメータ
  LCmdLine := ' -density 96'
            + ' ' + ExpandFileName('テスト.pdf[1-3]')
            + ' ' + ExpandFileName('TestAcro.jpg');

  ShellExecute(0, '', PChar(LCmdExePath), PChar(LCmdLine), nil, SW_HIDE);
end;


コマンドラインのパラメータを次のようにすると,元の PDF の 1 ページから 4 ページまでと 10 ページ目だけを取り出して別の PDF 文書を作成することができます.


  LCmdLine := 'テスト.pdf[0-3,9] TestAcro.pdf';


[備考]
Ghostscript を必要としないで PDF を画像にするコマンドラインツールがあります.下記のページの [Download the Xpdf tools] からダウンロードしたファイルの中に pdftopng.exe があります.これを使用すると PDF を PNG 形式の画像に変換できます.
ページのタイトルと同じ [Download XpdfReader] というのがありますが,これはインストールして利用する PDF ピューワです.




PascalMagick を使用して ImageMagick を利用


ImageMagick が提供している関数類を使用するには,DLL 版の ImageMagick をダウンロードしてインストールします.ImageMagick が提供している関数類を使用するということは,ImageMagick が提供している DLL 内の関数類を使用するということになります.
Free Pascal Compiler (Lazarus -ラザラス・ラザルス) 用に PascalMagick という ImageMagick 用の
ヘッダーファイルが提供されています.これは Delphi でも利用可能です.
共に以下のリンクからダウンロードできます.

筆者のテスト環境は 64 ビットの Windows 7 ですが,32 ビットの EXE を作成するので,ImageMagick は x86 の 32 ビット版をダウンロードしてインストールしました.64 ビットの EXE で使用する場合は x64 の 64 ビット版をダウンロードしてインストールします.Q16, Q8 の意味は本ページの最初に説明した通りです.
この DLL 版の ImageMagick にはコマンドラインツールも含まれています.



[備考]
ImageMagick のダウンロードのリストに static.exe というのがあります.今回ダウンロードしたのは dll.exe の方です.筆者は static.exe と dll.exe の違いについての知識はありません.



図5
ImageMagick のダウンロード
  • ダウンロードしたら EXE を起動してインストールする
図6
PascalMagick のダウンロード
  • ダウンロードしたら適当なフォルダに解凍する

PascalMagick をダウンロードして解凍したら,フォルダ内にある [magick] と [wand] というフォルダにライブラリパスを設定します.
次に ImageMagick.pas をテキストエディタで開き,以下の DLL 名を修正します.



  WandExport = 'CORE_RL_Wand_.dll';

      以下変更

  WandExport = 'CORE_RL_MagickWand_.dll';


これで準備ができました.uses に magick_wand, ImageMagick を追加して以下のコードを実行してみてください.画像ファイルのパス名は自分の環境に合わせて修正が必要です.このサンプルは本ページの最初のサンプルと同じように,PNG 画像を GIF 画像ファイルに変換します.ただし,今度は画像を半分のサイズにして変換しています.

ImageMagick のユニコード文字は UTF-8 です.したがって,以下のコードではファイル名の文字列変数を UTF8String 型で定義しています



リスト3
PascalMagick を使用して PNG 画像ファイルを GIF 形式の画像ファイルに変換する例
implementation

uses
  magick_wand,
  ImageMagick;

{$R *.dfm}

//=============================================================================
//  PascalMagickを使用してPNG形式の画像ファイルをGIF形式の画像ファイルに変換
//
//  [備考]
//  ファイル名の文字列はコードページをUTF-8とする
//  Ansi版のDelphiの場合はString型(Ansi版ではAnsiString型と同じ)で動作する
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LReadPath  : UTF8String;
  LWritePath : UTF8String;
  Lwand      : PMagickWand;
begin
  LReadPath  := ExpandFileName('logo.png');
  LWritePath := ExpandFileName('logo.gif');

  MagickWandGenesis;
  Lwand := NewMagickWand;
  try
    MagickReadImage(Lwand, PChar(LReadPath));
    MagickMinifyImage(Lwand);
    MagickWriteImage(Lwand, PChar(LWritePath));
  finally
    DestroyMagickWand(Lwand);
  end;
end;


文字列のキャストで警告が表示されるのが嫌な方は,以下のように明示的に UTF8String でキャストしてください.あるいはユニットの先頭に {$WARNINGS OFF} を追加すれば警告のメッセージは表示されなくなります.



procedure TForm1.Button1Click(Sender: TObject);
var
  LReadPath  : UTF8String;
  LWritePath : UTF8String;
  Lwand      : PMagickWand;
begin
  LReadPath  := UTF8String(ExpandFileName('logo.png'));
  LWritePath := UTF8String(ExpandFileName('logo.gif'));

  MagickWandGenesis;
  Lwand := NewMagickWand;
  try
    MagickReadImage(Lwand, Pointer(LReadPath));
    MagickMinifyImage(Lwand);
    MagickWriteImage(Lwand, Pointer(LWritePath));
  finally
    DestroyMagickWand(Lwand);
  end;
end;




ImageMagick で扱える画像形式をリスト


ImageMagick がサポートする画像形式の種類を調べてみました.以下はそのコードです.
MagickQueryFormats 関数は PascalMagick に実装されていないので,ImageMagick.pas の最後に以下を追加して実行しています.


function MagickQueryFormats(Pattern: PChar; var count: Integer): PPChar; 
  cdecl; external WandExport;


[備考 1]
PascalMagick は古いバージョンの ImageMagick の時代に作成されています.不足している関数類は,本サンプルの MagickQueryFormats 関数の例のように追加して利用することができます.
これは,Delphi に実装されていない Windows API を利用 (Windows が提供している DLL 内の関数を利用) する時と同じ方法です.


[備考 2]
画像の一覧のリストに DCR が表示されますが,これは Delphi のコンポーネントのアイコン画像ファイルのことではありません.コダックのデジタルカメラの画像ファイルの形式です.



図7
ImageMagick のバージョン情報
図8
ImageMagick がサポートしている画像形式のリスト

リスト4
ImageMagick のバージョン情報とサポートしている画像形式のリスト
implementation

uses
  magick_wand,
  ImageMagick;

{$R *.dfm}

//=============================================================================
//  ImageMagickのバージョン情報の取得
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LPAnsiCopy : PAnsiChar;
  LPAnsiVer  : PAnsiChar;
  LVersion   : Cardinal;
  LText      : String;
begin
  MagickWandGenesis;
  try
    LPAnsiCopy := PAnsiChar(MagickGetCopyright);
    LPAnsiVer  := PAnsiChar(MagickGetVersion(@LVersion));
    LText := string(LPAnsiCopy) + sLineBreak
           + string(LPAnsiVer) + '  ' + IntToStr(LVersion);
  finally
    MagickWandTerminus;
  end;
  MessageBox(Handle, PChar(LText), '情報', MB_ICONINFORMATION);
end;

//=============================================================================
//  ImageMagickがサポートする画像の種類のリスト
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
type
  PCharArray = array of PAnsiChar;
var
  LPattern   : UTF8String;
  LStr       : string;
  LPAChararr : PCharArray;
  LTypeCount : Integer;
  LTypeNo    : Integer;
begin
  try
    LPattern := '*';
    LPAChararr := PCharArray(MagickQueryFormats(PChar(LPattern), LTypeCount));

    ListBox1.Items.Clear;
    ListBox1.Items.BeginUpdate;
    for LTypeNo := 0 to LTypeCount - 1 do begin
      try
        LStr := LPAChararr[LTypeNo];
        if Trim(LStr) <> '' then begin
        ListBox1.Items.Add(FormatFloat('000', LTypeNo + 1) + '   ' + LStr);
        end;
      except
      end;
      Application.ProcessMessages;
    end;
    ListBox1.Items.Add('--------------------');
    ListBox1.Items.Add('Total : ' + IntToStr(LTypeCount));
    ListBox1.Items.EndUpdate;
    ListBox1.Update;
  finally
    SetLength(LPAChararr, 0);
  end;
end;




ImageMagick のコマンドライン実行で結果を取得する方法


上のサンプルのように ImageMagick の関数を使用すると,画像の情報等の結果を取得することができます.コマンドラインの実行でも結果を取得することができます.ただし,portable 版の場合,ダウンロードして解凍した先のフォルダ (ディレクトリ) にシステム的にパスが通っていないと利用できない機能があります.後述の PATH の設定の記事を参考にしてください.
portable 版ではなく,ImageMagick 本体をインストールした場合は,自動的にインストール先のフォルダが,環境変数の PATH のリストに追加されます.

コマンドラインのデフォルトの出力先は下図のように標準出力,つまり,コマンドプロンプトです.



図9
コマンドの実行結果の表示

当サイトで提供している「パイプを使用したコマンドラインのリダイレクト」のユニットを使用すると,結果を文字列として取得できるようになります.ただし,コマンドラインに渡す文字は ASCII 文字に限ります.漢字は UTF-8 の文字として正常に認識できません.
以下はそのユニットを使用した例です.画像ファイルのサイズ等の情報を TMemo に表示します.



図10
指定画像ファイルのサイズ等の情報を取得して表示
図11
画像の詳細な情報の取得例

リスト5
リダイレクトの機能を使用して ImageMagick のコマンドの実行結果を取得
implementation

uses
  plCommandRedirect;

{$R *.dfm}

//=============================================================================
//  ImageMagickのコマンド実行結果を取得
//  リダイレクトの機能を使用して結果を文字血で受け取る
//  画像のサイズ等の情報を取得する例
//
//  このコードは「文字列の暗黙的なキャスト」の警告が表示される
//  UTF-8で受け取ってUnicodeに変換しないと,内容によっては文字化けする
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LCmdRedirect : TplCommandRedirect;
  LCmdLine     : string;
  LResultStr   : UTF8String;
begin
  Memo1.Clear;
  Memo1.Update;

  LCmdRedirect := TplCommandRedirect.Create;
  try
    LCmdLine := 'magick identify logo.png';

    LResultStr := LCmdRedirect.GrabStdOutText(LCmdLine);
    Memo1.Text := UTF8ToUnicodeString(LResultStr);
  finally
    FreeAndNil(LCmdRedirect);
  end;
end;

//=============================================================================
//  ImageMagickのコマンド実行結果を取得
//  リダイレクトの機能を使用して結果を文字血で受け取る
//  画像の詳細な情報を取得する例
//
//  このコードは「文字列の暗黙的なキャスト」の警告が表示される
//  UTF-8で受け取ってUnicodeに変換しないと,内容によっては文字化けする
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LCmdRedirect : TplCommandRedirect;
  LCmdLine     : string;
  LResultStr   : UTF8String;
begin
  Memo1.Clear;
  Memo1.Update;

  LCmdRedirect := TplCommandRedirect.Create;
  try
    LCmdLine := 'magick identify -verbose logo.png';

    LResultStr := LCmdRedirect.GrabStdOutText(LCmdLine);
    Memo1.Text := UTF8ToUnicodeString(LResultStr);
  finally
    FreeAndNil(LCmdRedirect);
  end;
end;


前項で ImageMagick で扱える画像形式をリストしましたが,以下のコマンドを実行すると更に詳しい情報が取得できます.
この図には前項の [備考] で述べた DCR の説明があります.


    LCmdLine := 'magick identify -list format';


図12
図8 ImageMagick で扱える画像形式

[備考]
ImageMagick ではデジタル写真の Exif, GPS 等のメタデータを取得する等の操作ができますが,以下の GDI+ の記事で紹介している ExifTool や CCR Exif というツールもあります.




タイプライブラリの取り込みで ImageMagick を使用


DLL 版の ImageMagick をインストールする時,
  install ImageMagickObject OLE Control for VBscript,Visual Basic, and WSH
をチェックすると,タイプライブラリが作成されます.このタイプライブラリを取り込んでユニットを作成するとコンポーネントとしてフォーム配置したり,実行時に生成して利用できます.
ただし,機能的には ImageMagick のコマンドラインの機能しかありません.ImageMagick の関数類は実行てきません.
参考として,本ページの最初のサンプルと同じ処理をするコードを掲載しておきます.



[備考]
タイプライブラリの取り込みのユニットを使用して作成した EXE は,実行環境にも
   install ImageMagickObject OLE Control for VBscript,Visual Basic, and WSH
にチェックを入れて ImageMagick をインストールしないと正常に動作しません.



リスト6
タイプライブラリの取り込みで作成したユニットを使用する例
implementation

uses
  ActiveX,
  ImageMagickObject_TLB;

{$R *.dfm}

//=============================================================================
//  ImageMagickを使用してPNG形式の画像をGIF形式の画像に変換
//  タイプライブラリの取り込みで作成したユニットを使用する例
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LImgMagick : TMagickImage;
  LVarArray  : OleVariant;
begin
  LImgMagick := TMagickImage.Create(Self);
  try
    //コマンドを格納する配列を作成
    LVarArray := VarArrayCreate([0, 3], varVariant);

    //コマンドラインツールのオプションの指定と違うので注意
    //空白で区切って設定する値は各配列要素に格納する
    LVarArray[0] := ExpandFileName('logo.png');
    LVarArray[1] := '-resize';
    LVarArray[2] := '300';
    LVarArray[3] := ExpandFileName('logo.gif');

    LImgMagick.Convert(PSafeArray(TVarData(LVarArray).VArray));
  finally
    FreeAndNil(LImgMagick);
  end;
end;


実行結果はメソッドの戻り値で取得できます.以下はその例です.画像のサイズを取得して表示していますが,日本語の一部が違う文字になって戻ってきています.



図13
画像サイズの取得

リスト7
タイプライブラリの取り込みで作成したユニットを使用した,画像サイズの取得
procedure TForm1.Button1Click(Sender: TObject);
var
  LImgMagick : TMagickImage;
  LVarArray  : OleVariant;
  LMessage   : OleVariant;
  LStr       : string;
begin
  LImgMagick := TMagickImage.Create(Self);
  try
    //コマンドを格納する配列を作成
    LVarArray := VarArrayCreate([0, 2], varVariant);

    //空白で区切って設定する値は各配列要素に格納する
    LVarArray[0] := '-format';
    LVarArray[1] := '幅 : %w\n高さ : %h';
    LVarArray[2] := ExpandFileName('logo.png');

    LMessage := LImgMagick.Identify(PSafeArray(TVarData(LVarArray).VArray));
    LStr     := UTF8ToString(LMessage);
    MessageBox(0, PChar(LStr), '情報', MB_ICONINFORMATION);
  finally
    FreeAndNil(LImgMagick);
  end;
end;


ImageMagick では タイプライブラリの取り込みを ImageMagickObject.dll から行います.タイプライブラリの取り込みで作成したユニットを使用した EXE は,DLL の名前にある通り,ImageMagick を COM オブジェクト (OLE オブジェクト) として利用することを意味しています.したがって,ImageMagick をインストールしていない実行環境でこの DLL だけをシステムに登録しようとしても下図のようなエラーが発生します.
実行環境にも,開発環境と同じく [ImageMagickObject OLE Control] をチェックして ImageMagick をインストールします.そうすれば自動的に dll もシステムに登録してくれます.



図14
ImageMagickObject.dll 登録エラー

下図は Dependency Walker で ImageMagickObject.dll の依存関係を調べた結果です,
DLL 内部で別の mageMagick の DLL を使用していることが確認できます.これらはコマンドラインのコマンド,あるいはその DLL 内の関数を使用する際にも使われるものです.
つまり,ImageMagickObject.dll は,単独で ImageMagick の機能を実行するわけではありません.

ワードやエクセルも COM オブジェクトとして利用できますが,ImageMagick と同じように,実行環境にワードやエクセルがインストールされていないと利用できません.



図15
ImageMagickObject.dll の依存関係
  • 赤枠は ImageMagick インストール先のフォルタ内にある DLL




portable 版 ImageMagick 使用時の PATH の設定


本ページの最初で portable 版の ImageMagick を使用したサンプルを掲載しました. portable 版はインストール作業が必要ないのでアプリの配布には便利です.
しかし,ImaageMagick のフォルダにシステム的にパスが通っていないと利用できない機能があります.以下のように,アプリ実行時に環境変数の PATH を設定しておくと便利です.環境変数の PATH を設定すると,ディレクトリ名を省略して EXE を実行できます.

SetEnvironmentVariable 関数による環境変数の設定は,そのアプリのプロセスだけで有効となります.システムの環境変数の値を変更することはできません.SETX コマンドを使用するとシステムの環境変数の値を変更できます.SETX コマンドの実行には管理者権限が必要です.



リスト8
環境変数の PATH に ImageMagick 関係ファイルがある場所を追加する方法
portable 版の解凍先が C:\ImageMagick の場合の例
//=============================================================================
//  フォーム生成時の処理
//  ファイル検索用に,環境変数のPATHを設定
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
var
  LEnvStr   : string;
  LPathList : string;
begin
  LEnvStr := 'PATH';

  LPathList := GetEnvironmentVariable(LEnvStr);
  LPathList := 'C:\ImageMagick;' + LPathList;
  SetEnvironmentVariable(PChar(LEnvStr), PChar(LPathList));
end;


ShellExecute 関数,ShellExecuteEx 関数あるいは CreateProcess 関数でコマンドを実行する場合,作業フォルダを指定するとその作業フォルダがカレントディレクトリになります.このことを利用すると実行 EXE のディレクトリ名を省略することができます.
ただし,この方法は,上の環境変数による PATH の設定との違いに注意が必要です.例えば次のコードでは,logo.gif は,ShellExecute を実行したアプリケーションの EXE があるフォルダでなく,作業ディレクトリに作成されてしまいます.



リスト9
作業ディレクトリの指定で,実行するコマンド (EXE) の場所を設定する方法
//=============================================================================
//  PNG画像ファイルをGIF画像ファイルに変換
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LCmdExePath : string;
  LCmdLine    : string;
  LWorkDir    : string;
begin
  LCmdExePath := 'magick.exe';
  LWorkDir    := 'C:\ImageMagick';

  //コマンドパラメータ
  LCmdLine := ExpandFileName('logo.png')
            + ' -resize 300'
            + ' ' + 'logo.gif';

  ShellExecute(0, '', PChar(LCmdExePath), PChar(LCmdLine), PChar(LWorkDir), SW_HIDE);
end;