高見知英の技術ログ

技術関係のログをQiitaから移行してきました。プログラミングのほか、使っているアプリの細かい仕様についてなど書いていきます。

PowerShellでPowerPointのスライドをセクション別のファイルに分割する

とある事情で、PowerPointの以下のようなファイルを、セクションごとに別々のファイルに分けることになりました。

  • セクション1 # →セクション1.pptxとして保存
    • スライド1
    • スライド2
  • セクション2 # →セクション2.pptxとして保存
    • スライド3
    • スライド4
    • スライド5
  • セクション3 # →セクション3.pptxとして保存
    • スライド6

セクション三つくらいであれば別に手作業でもいいんですが、17セクションもあるとけっこうツラいので、PowerShellで作成することにしました。

OfficeアプリのCOMオブジェクトはリファレンスが追いづらく、あまり好きではないのですが・・・*1

というわけで

というわけでひとまずコードです。

$file = "$PSScriptRoot\雉・侭.pptx"
$app = New-Object -ComObject PowerPoint.Application
$pres = $app.Presentations.open($file)
$sec_name = ""
$curpres = $null
foreach($s in $pres.Slides){
  $cur_sec = $pres.SectionProperties.Name(($s.sectionIndex))
  if($sec_name -ne $cur_sec){
    if($sec_name -ne ""){
      # 前のプレゼンテーションファイルを保存して閉じる
      $curpres.SaveAs("$PSScriptRoot\$sec_name.pptx")
      $curpres.Close()
    }
    # 新しいプレゼンテーションファイルを作成する
    $curpres = $app.Presentations.Add()
    $sec_name = $cur_sec
  }
  if($null -ne $curpres){
    # スライドをコピーする
    $s.Copy()
    $newslide = $curpres.Slides.Paste()
    # 各種パラメータのコピー
    $newslide.Design = $s.Design
    $newslide.ColorScheme = $s.ColorScheme
    $newslide.DisplayMasterShapes = $s.DisplayMasterShapes
    $newslide.FollowMasterBackground = $s.FollowMasterBackground
  }
}
$curpres.SaveAs("$PSScriptRoot\$sec_name.pptx")
$curpres.Close()

$pres.Close()
$app.Quit()

とりあえず個々のメソッド解説はおいといて、すべてのスライドはPresentation.Slidesプロパティ、セクション名はPresentation.SectionPropetoesプロパティで取得できます。

案外Visual Studio Code上でもPowerShellスクリプトが編集できるということが分かって良かった(たしか要拡張機能)。PowerPointApplication.VisibleプロパティをmsoFalseにすればPowerPointアプリ自体を非表示にできる と書いてあったので試したものの、うちのバージョンではエラーが出て非表示にできなかった。

どれくらいの精度でコピーできる?

とりあえず、完璧ではない。

実際にスクリプト実行後すべてのファイルを見てみたものの、

  • コピーができなかったスライド(原因不明):1つ
  • レイアウトが崩れてしまった)スライド:2つ

あった。まあ92スライド中3スライドだけだったので上出来か。

レイアウトが崩れてしまう理由

レイアウトについてはスライドマスターの状態から多少でもレイアウトをいじっていると、確実に崩れるようで、スライドマスターに登録されていないレイアウトを使うと確実にずれます。

例えばわたしが良く使う上下に2コンテンツみたいなレイアウトとかをするときは、必ずそのレイアウトをスライドマスターに登録しておく必要があります(スライドマスターに登録してあれば問題ありません*2 )。

今回上手くいかなかったのは、スライドマスターの設定を変更し忘れたり、微妙にレイアウトを変更していたスライドでした。

スライドの確認は必須。でも効果は十分

はいっているはずのスライドがはいっていなかったり、レイアウトが崩れてしまったりなど、予期せぬ問題があるため、スライドの確認は必須。ただツールとしては十分有益だったかなと思います。

ComObjectの利用例は少ないためツールを作るのもそこそこに大変ですが、とりあえず使ってみる価値はあるかなと。

*1:PowerPointのリファレンスだっていうのにAccessとかExcelの情報とか平気で引っかかるし、一部のメソッド名が翻訳されてたりするし

*2:それでもそこから少しでもレイアウトをいじっているとやっぱりずれます

Pythonは複数変数に同時に値を設定できる

たいしたことではないですが覚えておくといろいろ役に立つのでメモ。

Pythonでは、関数の戻り値をtupleで得るなど、複数の値を1度に取得することがたまにあります。

たとえばtkinterでウィンドウの寸法を取得するには、window.geometry()で取得できる値を分割するのが簡単

  import re
  sizes = re.split("[x+]", window.geometry())

このときsizesの配列には、

  • 0: 幅
  • 1: 高さ
  • 2: X位置
  • 3: Y位置

という値がはいるのですが、同じようなコードが連続するとどれがどの値なのかぱっと見分かりづらくなる。

そんなときはこうすると良い。

  w, h, x, y = re.split("[x+]", window.geometry())

こうすると変数w,h,x,yにそれぞれの値がはいるので管理が楽。さらにintにするには

w, h, x, y = map(lambda s: int(s), re.split("[x+]", window.geometry()))

とすれば良い。tupleやlistに直さなくても良いんだ…。

どうということはないけど覚えておくと意外と役に立つ書き方でした。

NT札幌のイベントに参加してきました #NT札幌

一昨日12月26日(土)は、cluster上で行われたイベント、NT札幌に参加してきました。

当日は自分のオンラインイベント動画試聴会をやっていたので、その終わりにふとTwitterを見ていたのですが、ハッシュタグが気になってそのまま参加。こういうことが出来るのもオンラインならではのいいところですね。

clusterで開催されるセミナー系イベントは久しぶり。ハードウェアのことはあまりよく分からないので、ピンとこなかった点もありましたが、いつもとまた違うお話しを聞くことができ、楽しかったです。

f:id:TakamiChie:20201228093808p:plain
当日の様子

続きを読む

ログ出力の基本方針

このブログはエラー・ロギング Advent Calendar 2020 - Adventar18日目のブログです。

今回はプログラミングにおけるロギング処理について書いてみようと思います。

ロギングとは、プログラムの実行中にログを出力する処理。

1ファイルで完結する程度の簡単なプログラムならともかく、中規模のプログラムであれば、障害時の原因追跡のためにも、ログの出力は盛り込んでおきたい。

プログラムを組む段階では問題ないと思っていても、いざ開発を進めていくと、ログを出力していなかったせいで問題の原因がどこにあるか分からない なんてことは割とよくあることなのではないかと思います。

このためにも、プログラム作成に当たって、必要に応じてログを出力する というのは重要です。

続きを読む

TkSugarについてもう一度

このブログは、はんなりPython Advent Calendar 2020 - Qiita15日目の記事です。

TkSugarというのは、わたしがつくったモジュールで、YAML形式のファイルを読み込むと、それに準じたTkのウィンドウを生成する というモジュールです。

github.com

コントリビューションいただけると非常に助かります。

昨今のOSSの流行りに則り(?)コミットログやコメントは全文英語でやっています(Issueはさすがに無理なので英語)*1

サンプルはリポジトリsamplesフォルダに格納されています。tkinterを直接いじるのは結構コードが長くなり、なかなか骨が折れるので、一つの解決策として一つどうでしょうか。

はんなりPython方面では、10月のLT会でお話ししました。動画はSpeakerDeckの詳細ページから。

speakerdeck.com

*1:Visual Studio CodeComment Translateという拡張を使うとコメントは日本語で読むこともできるので、英語でもそれほどには困りません。多少は英語を読む機会が増えるため、なんとなく文意は拾えるようになりますし

続きを読む

stand.fmのカバー画像自動生成ツールについて

このブログは、【みんなのITもくもく会】自己紹介 Advent Calendar 2020 - Adventar8日目の記事です。

実はやってたstand.fm。わたしは基本的に、stand.fmはPCで録音して配信しています。

stand.fm

stand.fmはスマートフォンでしか使えないアプリなのですが、外部音源取り込み機能があるので、そこからOneDriveに保存した音源を読み込み、貼り付けて使っています。

OneDriveアプリをあらかじめ設定しておけば、とくに面倒なことなく音源を取り込むことができるので、不便なくPCからの取り込みが可能です*1

カバー画像を自動生成する

さて。そんなstand.fmですが、自分のフォロワーに毎回カバー画像にタイトルを埋め込んでいる人がおり、ちょっとやってみたいなーと思っていました。

その方は仕事でAdobe製品を使っているとのことで、毎回画像は手作りとのことだったのですが、そこはわたしです。ただ作るだけじゃつまらない。プログラミングで作らなくちゃ。

ということで作ったのが今回のstand.fm画像作成ツールです。

なお、ソースコードGithubにて公開しております。必要だったらテンプレートやフォントを変えて各自お好きな画像を作ってください。

github.com

やったこと

とりあえず最近使ってるのでPythonで。画像を作るならPIL(Python Image Library)だろと思いましたが、文章のワードラップとかフォントの調整とかをやろうとするとけっこう面倒。

なにかいいものがないかと探してみると、あるじゃないですか、HTMLを画像として取得できるライブラリが。

pypi.org

これは以前使ったPDFKitの兄弟モジュールみたいなもので、HTMLを画像に変換することができるというモジュール。

使い方はPDFKitとあまり変わらないため、PDFKitで悪戦苦闘した自分なら簡単です。

でもWebkitなんだよね・・・

でも、ImgKitはPDFKitと同じく、WebkitエンジンでHTMLをレンダリングします。

これが結構くせ者で、Chromeなどとはかなり違った*2レンダリングを行います。

いちおうWindows用のWebkitブラウザもあるにはあるのですが*3、手軽に作るのにいちいちWebkit用に調整するのは面倒くさい。

どうにか良い方法はないものか…。

そこでSeleniumですよ

そこでもう一つ見つけたのが、Seleniumスクリーンショット機能を使うというもの。

ヘッドレスブラウザとしてChromeを立ち上げ、画面を撮影すれば、Chromeとまったく同じ見た目で画像データを作成することができます*4。これは非常によい。

ということで作ったのが今回のツールです。

動作の流れ

今回やったのは非常に簡単です。

コマンドラインオプションで日付やテーマを受け取り(省略した場合は今日の日付や、あらかじめ曜日で定めたテーマを使用*5 )、もしmp3がすでにあればそのID3タグに設定されているタイトルを取得*6してそれを使用します。

エクスプローラからもその辺の設定がある程度調整できるよう、無駄にGUIも作りました(GUIモジュールの動作確認という側面もあるのですが)。オプション--guiをつけると、簡単なGUI画面が立ち上がります*7

f:id:TakamiChie:20201205193011p:plain
GUI(日付がmm/dd/yyなのは海外のtkcalendarというモジュールを使ったため)

ここでOKを押すと、OneDrive上のフォルダにout.pngという名前で画像が作られます。

f:id:TakamiChie:20201207105430p:plain
作成された画像

これをそのままスマートフォンから参照すれば、それっぽいカバー画像のついた投稿ができるという仕組み。

なお、ID3タグに書き込んだタイトルやコメントは、PushBulletを使ってスマートフォンに渡します。

今までは同種のソフトとしてJoinを使ってたんですが、なかなか設定が独特で、機種変更(や端末初期化)の時の再設定が面倒・・・。

www.pushbullet.com

いちおうOGPにも対応

いちおう画像のサイズを調整して、OGPでも枠線が表示されるようにしています。ただの背景つきピンクでは物寂しいので。

f:id:TakamiChie:20201207105319p:plain
Twitterでの表示イメージ

このへんの設定も、Less(CSS)ファイルをいじれば結構よろしくやってくれるのがHTMLデザインのいいところですね。

今回得た学び

HTML/CSSがある程度以上できる人が画像やPDFを作るときは、下手にLaTeXや画像処理を学ぶより、HTML書いた方がいい というのは個人的な思いでしたが、これをPythonのモジュールからも実現できるということがわかりました。

こちらについては今後も、定型的な画像を作成する機会などに使えるのではないかと思います(まあ今回はローカル環境で動作するだけだったのでSeleniumが使えましたが、たいていの場合はImgKitかな・・・)。

TkSugarの動作テストもできたしとりあえずわたしはそれなりに満足です。

ただ、タイトルのワードラップ回りなどいろいろできそうなところはあるので、もうちょっと時間を見つけていじってみたいですね。

*1:本当はstand.fm自体がPCからの直接アップロードに対応してくれれば一番楽なのですが

*2:とくにフォント方面で

*3:OtterBrowserとか

*4:title.py 75行目 あたり

*5:title.py 26行目あたり

*6:title.py 36行目あたり

*7:title.py 43行目あたり