# Delphi で PowerPoint の各ページを画像ファイルにする --- tags: Delphi COM programming PowerPoint objectpascal created_at: 2020-03-18 updated_at: 2020-03-19 --- # はじめに @natsutan さんの[『PythonでPowerPointの各ページを画像ファイルにする』](https://qiita.com/natsutan/items/2487e24fe3f31569b40d)という記事中にあるコードを Delphi で書いてみました。使用する Delphi のバージョンは **10.3.3 Rio** です。 # 移植 使い方などはオリジナルに準拠するものとします。 ## コード コンソールアプリケーションとして書かれており、ほぼベタ移植です。 ```pascal:PPT2PNG.dproj program PPT2PNG; {$APPTYPE CONSOLE} uses System.SysUtils, System.Win.ComObj, System.IOUtils; const PPT_NAME = 'test.pptx'; OUT_DIR = 'images'; procedure export_img(fname, odir: string); begin var application: OleVariant := CreateOleObject('Powerpoint.Application'); application.Visible := True; var current_folder := TDirectory.GetCurrentDirectory; var presentation := application.Presentations.open(TPath.Combine(current_folder, fname)); var export_path := TPath.Combine(current_folder, odir); presentation.Export(export_path, FilterName := 'png'); presentation.close; application.quit; end; { export_img } procedure rename_img(odir: string); begin for var fname in TDirectory.GetFiles(odir, '*.png', TSearchOption.soTopDirectoryOnly) do begin var new_fname := StringReplace(fname, 'スライド', 'slide', []); TFile.Move(fname, new_fname); end; end; { rename_img } begin export_img(PPT_NAME, OUT_DIR); rename_img(OUT_DIR); end. { main } ``` ところがこれを実行するとエラーが発生してしまいます。 ![image.png](./images/ea8ad9e9-683b-64d2-0cea-ebe4dd709453.png) ``` --------------------------- デバッガ例外通知 --------------------------- プロジェクト PPT2PNG.exe は例外クラス EOleSysError (メッセージ 'CoInitialize は呼び出されていません。')を送出しました。 --------------------------- ブレーク(B) 継続(C) ヘルプ --------------------------- ``` この問題はアプリケーションがコンソールアプリケーションの時に起こります。 ## 問題回避 問題を回避するには、**uses** に `Winapi.ActiveX` を加え、 ```pascal uses System.SysUtils, System.Win.ComObj, System.IOUtils, Winapi.ActiveX; // <-- 追加 ``` **COM** を使っているコードを `CoInitialize` と `CoUninitialize` で括ります。 ```pascal procedure export_img(fname, odir: string); begin CoInitialize(nil); // <- 追加 var application: OleVariant := CreateOleObject('Powerpoint.Application'); application.Visible := True; var current_folder := TPath.GetDirectoryName(ParamStr(0)); var presentation := application.Presentations.open(TPath.Combine(current_folder, fname)); var export_path := TPath.Combine(current_folder, odir); presentation.Export(export_path, FilterName := 'png'); presentation.close; application.quit; CoUninitialize; // <- 追加 end; { export_img } ``` ちゃんとやるなら `CoInitialize` と `CoUninitialize` は **try** ~ **finally** で括った方がいいと思います。 **See also:** - [COM (Wikipedia)](https://ja.wikipedia.org/wiki/Component_Object_Model) - [CoInitialize function (docs.microsoft.com)](https://docs.microsoft.com/ja-jp/windows/win32/api/objbase/nf-objbase-coinitialize) - [CoUninitialize function (docs.microsoft.com)](https://docs.microsoft.com/ja-jp/windows/win32/api/combaseapi/nf-combaseapi-couninitialize) # おわりに **でるお (仮)** のスライドが無事画像に変換できました! ![image.png](./images/9afa5d3c-ffe5-b3b1-4b1f-f420bc5d0a44.png) **See also:** - [Delphi (Embarcadero)](https://www.embarcadero.com/jp/products/delphi) - [Delphi Community Edition (Embarcadero)](https://www.embarcadero.com/jp/products/delphi/starter) - [Delphi のマスコットキャラが欲しい件 (Togetter)](https://togetter.com/li/622377)