業務上、PDFを扱う機会は多くなってきたが、署名を入れるだけ、透かしを入れるだけ、ページを抽出するだけ(けっこう多い…)など、ほんの少しの機能が使いたいだけなのに、adobeに年間数万支払うのも中小企業にとっては痛いので、最近テストでいろいろやっているPythonでうまくできないか調べてみた。
「PyPDF2」というライブラリを使えば、いろいろ出来るらしい。
PyPDF2は、Python用のPDF操作ライブラリであり、MITライセンスで提供されています。このライセンスにより、個人および商業利用が許可され、ソースコードの変更や再配布が可能です。著作権表示を残す必要があります。
便利な世の中になったもんだ
pdf_watermark.py
# pdf_watermark.py
# Copyright 2025 (c) Sketlab.LLC, T.Matsuoka
import argparse
from PyPDF2 import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from io import BytesIO
import os
def add_watermark(input_file, output_file, font_name, font_size, transparency, watermark_text):
try:
# カスタムフォントを登録
pdfmetrics.registerFont(TTFont(font_name, f"C:/Windows/Fonts/{font_name}.ttc"))
# 透かしを作成
packet = BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
can.setFont(font_name, font_size)
can.setFillAlpha(transparency)
# ページ全体に透かしを描画
page_width, page_height = letter
yy = 0
for x in range(100, int(page_width), 300): # 横方向の間隔
yy = 150 - yy
for y in range(0, int(page_height), 300): # 縦方向の間隔
can.saveState()
can.translate(x, y + yy)
can.rotate(45)
can.drawString(0, 0, watermark_text)
can.restoreState()
can.save()
packet.seek(0)
watermark = PdfReader(packet)
# 元のPDFを読み込み
reader = PdfReader(input_file)
writer = PdfWriter()
for page in reader.pages:
page.merge_page(watermark.pages[0])
writer.add_page(page)
# 保存
with open(output_file, "wb") as output_pdf:
writer.write(output_pdf)
print(f"透かし文字[{watermark_text}]を入れたPDF を {output_file} に保存しました。")
except FileNotFoundError:
print(f"エラー:ファイル {input_file} が見つかりません。")
except PermissionError:
print(f"エラー:出力ファイル {output_file} が開かれているため、書き込めません。ファイルを閉じて再実行してください。")
except Exception as e:
print(f"エラー:予期せぬエラーが発生しました: {e}")
if __name__ == "__main__":
print("Copyright (c) 2025 by Sketlab LLC., T.Matsuoka\n")
parser = argparse.ArgumentParser(description="Add watermark to a PDF file.")
parser.add_argument("input_file", help="Path to the input PDF file")
parser.add_argument("-o", "--output", help="Path to save the watermarked PDF file (default: wm_inputfilename)")
parser.add_argument("-f", "--font", default="msgothic", help="Font name to use for the watermark (default: msgothic)")
parser.add_argument("-s", "--size", type=int, default=64, help="Font size for the watermark (default: 64)")
parser.add_argument("-t", "--transparency", type=float, default=0.1, help="Transparency level of the watermark (default: 0.1)")
parser.add_argument("-w", "--word", default="COPY", help='Watermark text to apply (default: "COPY")')
args = parser.parse_args()
# 出力ファイルのデフォルト設定
if args.output is None:
base_name = os.path.basename(args.input_file)
dir_name = os.path.dirname(args.input_file)
args.output = os.path.join(dir_name, f"wm_{base_name}")
add_watermark(
input_file=args.input_file,
output_file=args.output,
font_name=args.font,
font_size=args.size,
transparency=args.transparency,
watermark_text=args.word,
)
手元の環境は、Python 3.13.2、PyPDF2 3.0.1。
アプリとして成立させるために色々やっていますが、細かいことは -h オプションをつけて起動してください。
python pdf_watermark.py -h
スケットラボでは”痒いところに手が届く”ツールやマクロの製作もお受けします。
まずは、お問い合わせからご連絡ください。