とある事情でキャプチャ画像を順番通りにPowerPointのスライドに差し込む必要が出たのですが、こんなのを手作業でやるのはめんどくさいのでで自動化する方法を探したところ、Ruby で PowerPoint ファイルを生成できるものを見つけました。
そこで、これを使って画像を pptx に差し込む処理を汎用的に使えるようなスクリプトにしてみました。現時点ではとりあえず動くレベルの試験実装ですが、最低限の目的は達せられました。awk が動く環境なら、Linux (Windows Subsystem for Linux), macOS, cygwin のどれでも動くはずです。
作業に必要な powerpoint gem のインストール
gem install powerpoint
でOKです。(必要に応じて su とか sudo してください)
画像一覧を標準入力から受け取って powerpoint gem で画像を差し込むスクリプトを生成する処理をつくる
とりあえずこんなふうに awk で実装してみました。ファイル名は generateImagePptx.awk
とでもつけておきます。
#!/usr/bin/awk -f BEGIN { print "#!/usr/bin/ruby" print "" print "require \"powerpoint\"" print "@deck = Powerpoint::Presentation.new" print "" } { printf "title = \"%s\"\n", $1 ; printf "image_path = \"%s\"\n", $1 ; print "@deck.add_pictorial_slide title, image_path" ; print "" } END { print "@deck.save('images.pptx')" }
これで images.pptx に対して、指定されたファイル一覧を差し込む(正確には新規作成する)処理が生成できます。
実行してみる
png形式のファイルをまるごと渡すとスクリプトが作られるので、たとえば次のように実行するとよいでしょう。
ls *.png | generateImagePptx.awk | ruby
こうすれば、生成されたスクリプトがそのまま ruby 経由で実行されます。
差し込まれる画像の順番が思ったとおりにならない場合の対処
ファイル名の命名規則によっては思った通りの順番にならないことがあります。たとえばファイル名が slide-1.png, slide-2.png のように命名されていると、ls の結果が次のようになってしまい、意図通りの順になりません。
$ ls -l *.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-1.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-10.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-2.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-3.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-4.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-5.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-6.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-7.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-8.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-9.png
画像ファイルのタイムスタンプが時系列に並んでいるならば、-tr をつけてあげれば次のように意図通りに並びます。
$ ls -ltr *.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-1.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-2.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-3.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-4.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-5.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-6.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-7.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-8.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-9.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-10.png
しかしなんらかの理由でタイムスタンプが時系列順ではない場合は、この方法では思った通りの順番で出力できません。
$ ls -ltr *.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-1.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-3.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-4.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-6.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-7.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-8.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-9.png -rw-r--r-- 1 pslabo staff 0 6 15 06:49 slide-10.png -rw-r--r-- 1 pslabo staff 0 6 15 06:50 slide-5.png -rw-r--r-- 1 pslabo staff 0 6 15 06:50 slide-2.png
この場合は sort コマンドを間に挟みつつ slide-number.png を -t -
で slide と number.png に分割し、number.png の部分を -k 2 -n
で数値順ソートすれば意図通りの順番に並べることができます。
$ ls *.png | sort -t - -k 2 -n | xargs -n 1 ls -l -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-1.png -rw-r--r-- 1 pslabo staff 0 6 15 06:50 slide-2.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-3.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-4.png -rw-r--r-- 1 pslabo staff 0 6 15 06:50 slide-5.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-6.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-7.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-8.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-9.png -rw-r--r-- 1 pslabo staff 0 6 15 06:49 slide-10.png
したがって、次のように実行すればファイルのタイムスタンプによらず順番に画像を差し込んだ pptx を生成できます。
ls *.png | sort -t - -k 2 -n | generateImagePptx.awk | ruby
これでとりあえず最低限の目的は達せられていますが、ruby を別コマンドで実行しなければならない点がイマイチです。ここは print や printf の後に | "/usr/bin/ruby" をつけて awk のスクリプト内で ruby と連携したほうがよいですね。