🧰

PowerPoint スライドに透かしを入れる

2024/06/20に公開

こんな方に

  • PowerPoint ファイルに透かし(Watermark)を入れて配布する必要がある
  • ファイルがたくさんある
  • 何回も異なる透かしを入れて配る
  • PDFに変換する必要もあり

はい、これ。

https://github.com/npwsh/Add-Watermark

使い方

パラメータが多いので cmd.exe からではなく、pwsh.exe からの起動が推奨です(タブ補完してください)

pwsh .\Add-Watermark.ps1 [options]

処理としては 元ファイル + 透かし ⇒ 透かしの入ったファイル(新規作成)を行います。

オプションは以下。

オプション 意味・用途
-File <pptx> 透かしを入れる元ファイルを指定する
-Folder <dir> 複数の PPTX ファイルがあるフォルダを一括処理
-WatermarkTemplate <pptx> 透かしのデータを入れた PPTX ファイル
-Destination <dir> 作成したファイルの保管先を指定

-File または -Folder のどちらかは必須で処理対象の元ファイルを指定します。
-WatermarkTemplate は入れたい透かしを作っておきます。必須。
-Destination は作成したファイルを別フォルダに置くときに使用します。 -Folder と一緒に使う想定。

その他のオプション:

オプション 意味・用途
-Suffix <string> 元のファイル名ベース部分に指定の文字を追加します。%yyyy%, %MM%%, %dd% で年月日をそれぞれ指定することも可
-OldSuffix <string> 元ファイル名ベース部分の指定文字を削除したファイル名とします
-SaveAsPDF PDFファイルも作成
-SendToBack 透かしデータを最背面に

-OldSuffix は例えば月次報告など定期的に更新する PPTX があった場合に使います。例えば、月次報告-202405.pptx があってこれを6月用に更新する際に、[内容を更新してこれを消す] というテキストボックスだけスライド1に入れた updatemarker.pptx を作っておき、

.\Add-Watermark.ps1 -File 月次報告-202405.pptx -OldSuffix '-202404' -Suffix '-202405' -WatermarkTemplate updatemarker.pptx

とすると各スライドに [内容を更新してこれを消す] が入った 月次報告-202406.pptx ができる、と。あとはこのファイルをメンバーで共編集しつつ報告スライドを完成すれば。

透かしとちゃう? そやね。でも便利なのよ。

-SendToBack がないと最前面に透かしを追加します。コンテンツが見えなくなる(かも)というのが問題な場合はこれで最背面に。もちろん透かしが隠れて見えなくなることもあります。

注意

なぜこれが必要なのか?

PPT でも WORD でも Watermark 機能はあるのでそれを普通に使えばいいのですが、PPT の場合、全スライドに入れるのは結構面倒なうえ、そもそもがあちこちからスライドを集めてくつったデッキになっていることも多く、スライドマスターが統一されていなかったりと面倒です。作業するファイルがいくつもある、とか、ファイルが1つだけど配布先ごとに複数回作り分けるとかなると標準機能でどうこうなる気がしません(今後は Copilot が何とかしれくれるのか?)。

処理内容

特に凝った処理はしていなくて、

  1. 透かしデータファイルを開いてシェイプ情報を読み込む
  2. 元ファイルを別名でコピーして開き、1) でとってきた透かしデータを全スライドに追加
    1. を対象ファイル分繰り返す

簡単ですね。

透かしシェイプをスライドに追加する際に、Top, Left, Width, Height をオブジェクト作成時と最後に計2回設定していますが、フォントや外枠などを設定すると位置がそれに応じて変わるので、最終的に元の位置にもとすために設定しなおす必要があるからです。

エラー処理? 雑です。
透明度? やった方がいいかもしれん。

透かしのデータ

透かしデータは -WatermarTemplate オプションで指定するファイルに入っているものを使います。

Add-Watermark.ps1
class WatermarkShape {
    $Top; $Left; $Width; $Height;
    $Rotation;
    $Font;
    $Line;
    $Fill;
    $TF_Orientation;
    $TF_HAnchor; $TF_VAnchor;
    $TF_MarginTBLR;
    $TF_TR_Text;
    $TF_TR_PF_Alignment;

こんな感じでクラスを定義して各種プロパティ値を持っておく変数を用意しておきます。フォントや外枠線などは別クラスにしてもいいのですが、処理するコードがそこまで変わるわけでもなく、別クラス化する意味もあんまりないので取り込んでます。

Add-Watermark.ps1
 WatermarkShape($s) {
        $this.Top = $s.Top
        $this.Left = $s.Left
        $this.Width = $s.Width
        $this.Height = $s.Height
        $this.Rotation = $s.Rotation
        $this.GetFontInfo($s)
        $this.GetLineInfo($s)
        $this.GetFillInfo($s)
        $this.TF_Orientation = $s.TextFrame.Orientation
        $this.TF_HAnchor = $s.TextFrame.HorizontalAnchor
        $this.TF_VAnchor = $s.TextFrame.VerticalAnchor
        $this.TF_MarginTBLR = @(
            $s.TextFrame.MarginTop,
            $s.TextFrame.MarginBottom,
            $s.TextFrame.MarginLeft,
            $s.TextFrame.MarginRight)
        $this.TF_TR_Text = $s.TextFrame.TextRange.Text
        $this.TF_TR_PF_Alignment = $s.TextFrame.TextRange.ParagraphFormat.Alignment
    }

でもってコンストラクターで Shape を貰って必要そうな値は覚えておく、と。

Add-Watermark.ps1
    AddToSlide($slide) {
        $tb = $slide.Shapes.AddTextbox($this.TF_Orientation, $this.Left, $this.Top, $this.Width, $this.Height)
        $tb.Rotation = $this.Rotation
        (
            $tb.TextFrame.MarginTop,
            $tb.TextFrame.MarginBottom,
            $tb.TextFrame.MarginLeft,
            $tb.TextFrame.MarginRight) = $this.TF_MarginTBLR
        $tb.TextFrame.TextRange.Text = $this.TF_TR_Text
        $tb.TextFrame.TextRange.ParagraphFormat.Alignment = $this.TF_TR_PF_Alignment
        $tb.TextFrame.Orientation = $this.TF_Orientation
        $tb.TextFrame.HorizontalAnchor = $this.TF_HAnchor
        $tb.TextFrame.VerticalAnchor = $this.TF_VAnchor

        $this.SetFontInfo($tb)
        $this.SetLineInfo($tb)
        $this.SetFillInfo($tb)

        $tb.Width = $this.Width
        $tb.Height = $this.Height
        $tb.Left = $this.Left
        $tb.Top = $this.Top

あとは、元PPTファイルをコピーした後のスライドにテキストボックスを作って、覚えておいた属性値を戻していくだけですね。力技。

全部の属性値を取ってきているのかというと正直怪しいのですが、凝った透かしを入れるのでなければこの程度で十分でしょう。

実行例

例えばこういうスライドがあったとして(パワポのオンラインテンプレートそのままです)。

このような透かしデータ用のPPTXファイルを作ります。

その結果がこんな感じ。

Discussion