PR

【Python】 PDF に 透かし を入れる方法

python-dev Flask
python-dev
この記事は約8分で読めます。
記事内に広告が含まれています。

この記事では、Python で PDF に 透かし を入れる方法を紹介します。

Python では PDF を扱うライブラリも豊富なので、すぐできるんじゃないかと思ったら、本当にすぐにできました。

せっかくなので、実用性も兼ねて Flask で実装してみます。

環境構築

【Python】仮想環境 venv のセットアップ手順
仮想環境は、プロジェクトごとに異なるパッケージやPythonのバージョンを独立して管理するための環境を提供します。仮想環境にはいくつか種類がありますが、本記事では Python 3.3以降に標準で含ま...

こちらの記事を参考に、任意の作業ディレクトリで仮想環境を構築しましょう。

  • 仮想環境を作成
python -m venv venv
  • 仮想環境を有効化
# macOS/Linuxの場合
source venv/bin/activate

# Windowsの場合
venv\Scripts\activate
  • ライブラリのインストール
pip install PyPDF2 reportlab Flask

今回は、 PyPDF2, reportlab を使用します。 Flask で構築するので一緒にインストールします。

透かし ロジックの実装

早速ですが実装です。

watermark.py を作成します。

from io import BytesIO
from PyPDF2 import PdfWriter, PdfReader
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter

def add_watermark(input_file, output_file, watermark_text):
    # 透かしを作成
    packet = BytesIO()
    can = canvas.Canvas(packet, pagesize=letter)
    can.setFont("Helvetica", 60)
    can.setFillColorRGB(1, 0, 0, alpha=0.5)
    can.saveState()

    # 透かしの位置を計算
    watermark_width = can.stringWidth(watermark_text, "Helvetica", 60)
    watermark_height = 60
    x = (letter[0] - watermark_width) / 2
    y = (letter[1] - watermark_height) / 2

    can.translate(x, y)
    can.rotate(45)
    can.drawString(0, 0, watermark_text)
    can.restoreState()
    can.save()
    packet.seek(0)
    watermark = PdfReader(packet)

    # 元のPDFを開く
    existing_pdf = PdfReader(open(input_file, "rb"))
    output = PdfWriter()

    # 各ページに透かしを適用
    for page in existing_pdf.pages:
        page.merge_page(watermark.pages[0])
        output.add_page(page)

    # 透かしを適用したPDFを保存
    with open(output_file, "wb") as outputStream:
        output.write(outputStream)

処理の流れはみてもらえばわかると思うのですが、 canvas に透かしを書いて、 PDF にマージして返してあげると言う仕組みです。

表示位置や色、フォントなどは要件に応じて変えてくださいね。

スポンサーリンク

Flask の他の処理の構築

ロジックは先ほどのコードだけなので、あとは画面と起動処理を書いていきます。

  • app.py
from flask import Flask, request, send_file, render_template
from watermark import add_watermark

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file:
            input_file = 'input.pdf'
            output_file = 'output.pdf'
            file.save(input_file)
            add_watermark(input_file, output_file, 'Confidential')
            return send_file(output_file, as_attachment=True)
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

画面表示は GET, 透かし 処理のリクエストは POST で処理します。

Confidential と言う文字列を入れてみます。

  • templates/index.html
<!DOCTYPE html>
<html>
<head>
    <title>PDFに透かしを入れてみるよ</title>
    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100">
    <div class="container mx-auto px-4 py-8">
        <h1 class="text-3xl font-bold mb-4">PDFに透かしを入れてみるよ</h1>
        <form method="post" enctype="multipart/form-data" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
            <div class="mb-4">
                <label class="block text-gray-700 text-sm font-bold mb-2" for="file">
                    PDFファイルを選択
                </label>
                <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="file" type="file" name="file">
            </div>
            <div class="flex items-center justify-between">
                <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="submit">
                    透かしを入れる
                </button>
            </div>
        </form>
    </div>
</body>
</html>

HTML だけだと味気ないので、 TailwindCSS でいい感じにデザインしています。

【CSS】 TailwindCSS で美しいレスポンシブなデザインを実現
この記事では、 TailwindCSS で美しいレスポンシブなデザインを実現する方法を紹介します。私は本業で、Bootstrap, Material UI(MUI), 個人開発で FlatUI など、...

python-watermark-01

スポンサーリンク

動作確認

python app.py

をターミナルもしくはコマンドプロンプトで実行すると、 localhost:5000 が起動します。

アクセスすると先ほどの画面が表示されるので、 PDF をアップロードしてみてください。

sample-pdf

このサンプル PDF を使ってみます。

python-watermark-02

ちゃんと透かしが入ってますね。良い感じです。

スポンサーリンク

おわりに

業務上のセキュリティ要件などもあると思うので、手順を知っておいて損はないですね。

python はライブラリも豊富で使いやすいので、このようなサクッと検証に向いてますね。

コメント

タイトルとURLをコピーしました