【簡単Python】PDFに電子スタンプを押す方法
![](https://jitsuyogaku.com/wp-content/uploads/2024/06/qrcode_jitsuyogaku.com20240408python-create-menu-with-tabs.png)
![アイキャッチ画像](https://jitsuyogaku.com/wp-content/uploads/2024/11/PythonでPDFに電子スタンプを押す_20250211-1024x538.webp)
![](https://jitsuyogaku.com/wp-content/uploads/2024/04/ポテ-004_20240414131827-リサイズ-1.png)
いつもありがとうございます。
「ノンプログラマー向けPython解説シリーズ」へようこそ。
本稿では、「PDFに電子スタンプを押す方法」を解説いたします。
電子スタンプとは、次の図に示す「参考」のように、電子的に押されたスタンプのことを指します。これは、紙にハンコとインクで物理的に押すスタンプではなく、PDFファイル上に直接電子的に描画されたものです。
![電子スタンプのイメージ図](https://jitsuyogaku.com/wp-content/uploads/2024/11/20241127-004-png.webp)
市販の有料アプリケーションソフトウェアでは、高度なPDF編集が可能ですが、費用がかさむのが難点です。一方、Pythonでアプリを自作すれば、コストを抑えつつ、目的に合わせた柔軟なツールを作成できます。
Pythonで自分に合ったアプリを作成し、仕事量は半分に、成果は2倍にしていきましょう。
初心者でも理解しやすいように、分かりやすく解説していきます。ぜひ、ご覧ください。
Pythonで「PDFに電子スタンプを押す方法」
アプリの仕様
![](https://jitsuyogaku.com/wp-content/uploads/2024/03/PA076913-cropped_resized.png)
次のようなディレクトリ構成です。
program/
├── main.py
├── input.pdf
├── output.pdf
└── fonts/
└── YuGothB.ttc
main.py
がPythonコードが記述されたプログラムです。このプログラムが、input.pdf
を読み込み、スタンプを押したものをoutput.pdf
として出力します。
fonts
ディレクトリ内にある YuGothB.ttc
はフォントファイルです。main.py
がスタンプのテキストを生成する際に使用します。なお、フォントファイルは、Windowsであれば通常次のディレクトリに保存されています。ここから、必要なフォントファイルをfonts
ディレクトリにコピーして使うと良いでしょう。
C:\Windows\Fonts
どのようなスタンプを押すか(たとえば「参考」や「社外秘」など)は、コード内で指定します。このスタンプの内容は、GUI(グラフィカル・ユーザー・インターフェース)を作成して、その中で指定するようなアプリにすることもできますが、本稿ではその部分は省略します。
ことばの意味
- ディレクトリ
ディレクトリとフォルダは、どちらもコンピュータ上でファイルを整理・管理するための「入れ物」を指します。ディレクトリは、技術的な用語で、プログラミングやコマンドライン操作など専門的な場面で使われます。フォルダは、一般的な用語で、パソコンの画面上でファイルを整理する際に使われます。デスクトップやエクスプローラーで見かける「フォルダ」のことです。ディレクトリとフォルダは基本的に同じものです。違いは呼び方や使われる場面だけで、役割や機能に大きな差はありません。 - GUI(グラフィカルユーザーインターフェース)
ユーザーとコンピューターがコミュニケーションするための視覚的なインターフェースです。インターフェースとは接点のことです。ウィンドウ、ボタン等のグラフィカルな要素を使用してユーザーとコンピューターがコミュニケーションできるようにします。
コード全文
![](https://jitsuyogaku.com/wp-content/uploads/2024/08/PA076914-cropped_resized.png)
上述の仕様のアプリを作成するためのコードと、その実行結果を示します。
# 標準ライブラリのインポート
import io # バイトストリームを扱うために使用
# 外部ライブラリのインポート
from reportlab.pdfgen.canvas import Canvas # PDFの描画を行うためのモジュール
from reportlab.lib.colors import Color # 色を扱うためのモジュール
from reportlab.pdfbase.ttfonts import TTFont # TrueTypeフォントを使用するためのモジュール
from reportlab.pdfbase import pdfmetrics # フォントの登録やメトリクスを扱うためのモジュール
import PyPDF2 # PDFの読み書きを行うためのモジュール
class PDFHandler:
"""
PDFの作成、および既存のPDFにテキストを重ねる処理を行うクラス。
主な機能:
- フォントを登録する
- 新しいPDFレイヤーを作成する
- 新しいPDFレイヤーにテキストを描画する
- テキストを描画したPDFレイヤーと既存のPDFを重ねる
"""
def __init__(self, source_pdf_path, destination_pdf_path, font_file_path):
"""
クラスを初期化し、入力PDF、出力PDF、フォントのパスを設定する。
:param source_pdf_path: 入力用のPDFファイルパス
:param destination_pdf_path: 出力用のPDFファイルパス
:param font_file_path: フォントファイルのパス
"""
self.source_pdf_path = source_pdf_path # 入力元のPDFファイルパスを記憶
self.destination_pdf_path = destination_pdf_path # 出力先のPDFファイルパスを記憶
self.font_file_path = font_file_path # フォントファイルのパスを記憶
def register_font(self, font_name):
"""
フォントを登録する。
:param font_name: 登録するフォントの名前
"""
pdfmetrics.registerFont(TTFont(font_name, self.font_file_path)) # フォントをReportLabに登録
@staticmethod
def draw_text_with_border(canvas_obj, content, font_name, font_size,
font_color, text_padding, transparency):
"""
キャンバスにテキストとその周囲の枠線を描画する。
:param canvas_obj: ReportLabのCanvasオブジェクト
:param content: 描画するテキスト
:param font_name: フォントの名前
:param font_size: フォントサイズ
:param font_color: テキストと枠線の色(RGBタプル)
:param text_padding: テキストと枠線間の余白
:param transparency: テキストと枠線の透明度(0.0〜1.0)
"""
# 色と透明度を設定
text_color = Color(
font_color[0] / 255.0, # 赤色の値を0〜1に正規化
font_color[1] / 255.0, # 緑色の値を0〜1に正規化
font_color[2] / 255.0, # 青色の値を0〜1に正規化
alpha=transparency # 透明度を設定
)
canvas_obj.setFillColor(text_color) # テキストの塗りつぶし色を設定
canvas_obj.setStrokeColor(text_color) # 枠線の色を設定
canvas_obj.setStrokeColor(text_color) # 枠線の色を設定
canvas_obj.setFont(font_name, font_size) # フォントとサイズを設定
# テキストの描画
canvas_obj.drawString(0, 0, content) # 原点(0,0)にテキストを描画
# 枠線の描画
text_width = pdfmetrics.stringWidth(content, font_name, font_size) # テキストの幅を計算
text_height = font_size # テキストの高さはフォントサイズと同じ
canvas_obj.setLineWidth(1) # 枠線の太さを設定
canvas_obj.rect(
-text_padding, # 左側の余白
-text_padding, # 下側の余白
text_width + 2 * text_padding, # 枠線の幅
text_height + 2 * text_padding # 枠線の高さ
)
def create_text_layer_for_page(self, content, font_name, font_size, font_color,
text_x, text_y, text_padding, page_width, page_height,
text_rotation_angle=0, transparency=0.5):
"""
指定したテキストを含むPDFのページを作成する。
:param content: 描画するテキスト
:param font_name: フォントの名前
:param font_size: フォントサイズ
:param font_color: テキストと枠線の色(RGBタプル)
:param text_x: 描画位置のX座標
:param text_y: 描画位置のY座標
:param text_padding: テキストと枠線間の余白
:param page_width: ページの幅
:param page_height: ページの高さ
:param text_rotation_angle: テキストの回転角度(度単位)
:param transparency: テキストと枠線の透明度(0.0〜1.0)
:return: 作成したPDFページを含むBytesIOオブジェクト
"""
self.register_font(font_name) # フォントを登録
packet = io.BytesIO() # バイナリストリームを作成(メモリ内でPDFデータを一時的に保存)
canvas_obj = Canvas(packet, pagesize=(page_width, page_height)) # キャンバスを作成
canvas_obj.saveState() # キャンバスの現在の状態を保存
try:
canvas_obj.translate(text_x, text_y) # 描画位置に移動
canvas_obj.rotate(text_rotation_angle) # テキストを回転
self.draw_text_with_border( # テキストと枠線を描画
canvas_obj, content, font_name, font_size,
font_color, text_padding, transparency
)
except Exception as e:
raise RuntimeError(f"Failed to draw text or border: {e}") # エラーが発生した場合
finally:
canvas_obj.restoreState() # キャンバスの状態を復元する。
# ここで復元されるのは座標系や色、フォント設定などの状態であり、
# すでに描画された内容(テキストや図形)は消えない。
canvas_obj.showPage() # ページの描画を確定
canvas_obj.save() # PDFを保存
packet.seek(0) # バイナリストリームの先頭に戻す(後続の処理で読み込むため)
return packet # 作成したPDFページを含むバイナリストリームを返す
@staticmethod
def get_page_dimensions(page):
"""
ページの幅、高さ、回転角度を取得する。
:param page: PyPDF2のページオブジェクト
:return: (幅, 高さ, 回転角度)のタプル
"""
rotation = page.get("/Rotate", 0) # 回転角度を取得(デフォルトは0)
rotation = rotation % 360 # 回転角度を0〜359度に正規化
media_box = page.mediabox # ページのサイズ情報を取得
width = float(media_box.width) # ページの幅を取得
height = float(media_box.height) # ページの高さを取得
return width, height, rotation # 幅、高さ、回転角度を返す
def add_text_layer_to_page(self, page, content, font_name, font_size,
font_color, text_x, text_y, text_padding,
text_rotation_angle, transparency,
page_width, page_height):
"""
既存のPDFページにテキストレイヤーを重ねる。
:param page: PyPDF2のページオブジェクト
:param content: 描画するテキスト
:param font_name: フォントの名前
:param font_size: フォントサイズ
:param font_color: テキストと枠線の色(RGBタプル)
:param text_x: 描画位置のX座標
:param text_y: 描画位置のY座標
:param text_padding: テキストと枠線間の余白
:param text_rotation_angle: テキストの回転角度(度単位)
:param transparency: テキストと枠線の透明度(0.0〜1.0)
:param page_width: ページの幅
:param page_height: ページの高さ
"""
# 新しいテキストレイヤーを作成
text_layer_pdf = self.create_text_layer_for_page(
content, font_name, font_size, font_color,
text_x, text_y, text_padding, page_width, page_height,
text_rotation_angle, transparency
)
text_layer_reader = PyPDF2.PdfReader(text_layer_pdf) # テキストレイヤーを読み込む
text_page = text_layer_reader.pages[0] # 最初のページを取得
page.merge_page(text_page) # テキストレイヤーを既存のページに重ねる
def merge_pdfs(self, content, font_name='CustomFonts', font_size=12,
font_color=(0, 0, 0), text_x=0, text_y=0, text_padding=10,
specific_page=None, apply_to_all_pages=False,
text_rotation_angle=0, transparency=0.5):
"""
既存のPDFにテキストを重ね、新しいPDFを作成する。
:param content: 追加するテキスト
:param font_name: フォントの名前
:param font_size: フォントサイズ
:param font_color: テキストと枠線の色(RGBタプル)
:param text_x: 描画位置のX座標(左上原点)
:param text_y: 描画位置のY座標(左上原点)
:param text_padding: テキストと枠線間の余白
:param specific_page: テキストを追加する特定のページ番号(0基準)。
apply_to_all_pages が True の場合、この値は無視される。
:param apply_to_all_pages: 全ページに適用するか(Trueなら全ページ)
:param text_rotation_angle: テキストの回転角度(度単位)
:param transparency: テキストと枠線の透明度(0.0〜1.0)
"""
with open(self.source_pdf_path, "rb") as f_input:
reader = PyPDF2.PdfReader(f_input) # 入力PDFを読み込む
writer = PyPDF2.PdfWriter() # 出力PDFのライターを作成
# PDFの各ページを処理
for i, page in enumerate(reader.pages):
# ページの幅、高さ、回転角度を取得
page_width, page_height, rotation = self.get_page_dimensions(page)
# 対象ページかどうかを判定
if apply_to_all_pages or (specific_page is not None and i == specific_page):
rotation = rotation % 360 # 回転角度を正規化
# 回転角度に応じて座標と回転を調整
if rotation == 0:
adjusted_x = text_x
adjusted_y = page_height - text_y - font_size
adjusted_rotation_angle = text_rotation_angle
elif rotation == 90:
adjusted_x = text_y + font_size
adjusted_y = text_x
adjusted_rotation_angle = text_rotation_angle + 90
elif rotation == 180:
adjusted_x = page_width - text_x
adjusted_y = text_y + font_size
adjusted_rotation_angle = text_rotation_angle + 180
elif rotation == 270:
adjusted_x = page_width - text_y - font_size
adjusted_y = page_height - text_x
adjusted_rotation_angle = text_rotation_angle + 270
else:
adjusted_x = text_x
adjusted_y = page_height - text_y - font_size
adjusted_rotation_angle = text_rotation_angle
# テキストレイヤーをページに追加
self.add_text_layer_to_page(
page, content, font_name, font_size,
font_color, adjusted_x, adjusted_y, text_padding,
adjusted_rotation_angle, transparency,
page_width, page_height
)
# ページを出力PDFに追加
writer.add_page(page)
# 出力PDFを保存
with open(self.destination_pdf_path, "wb") as f_output:
writer.write(f_output)
# 処理完了のメッセージを表示
print("Text added to PDF successfully.")
def main():
"""
既存のPDFにテキストと枠線を重ねる処理を行う。
この関数では、PDFHandlerクラスを利用して次の処理を実行する:
- 入力PDFと出力PDFの指定
- テキストの内容、位置、フォント、サイズ、透明度の設定
- 指定されたページまたは全ページにテキストを重ねる処理
"""
# PDF編集に必要な設定を指定
source_pdf_path = 'input.pdf' # 入力元のPDFファイルパス
destination_pdf_path = 'output.pdf' # 出力先のPDFファイルパス
content = '参考' # PDFに描画するテキスト
font_size = 22 # テキストのフォントサイズ
font_color = (255, 0, 0) # テキストの色(RGB形式)
font_file_path = 'fonts/YuGothB.ttc' # 使用するフォントファイルのパス
specific_page = 0 # テキストを追加するページ番号(0基準)
# apply_to_all_pages が True の場合、この値は無視される
apply_to_all_pages = True # 全ページに適用するか(Trueなら全ページ)
text_rotation_angle = 5 # テキストの回転角度(度単位)
text_x = 50 # テキスト描画位置のX座標(左上原点)
text_y = 50 # テキスト描画位置のY座標(左上原点)
text_padding=10 # テキストの余白を指定
# PDF操作クラスのインスタンスを作成
pdf_handler = PDFHandler(
source_pdf_path,
destination_pdf_path,
font_file_path
)
# PDFにテキストを重ねる処理を実行
pdf_handler.merge_pdfs(
content, # 追加するテキスト
font_name="YuGothB", # 使用するフォント名
font_size=font_size, # フォントサイズ
font_color=font_color, # フォントの色
text_x=text_x, # テキストのX座標
text_y=text_y, # テキストのY座標
text_padding=text_padding, # テキストの余白を指定
specific_page=specific_page, # 特定のページ番号
apply_to_all_pages=apply_to_all_pages, # 全ページに適用するか
text_rotation_angle=text_rotation_angle, # テキストの回転角度
transparency=0.3 # 透明度
)
if __name__ == "__main__":
main()
![](https://jitsuyogaku.com/wp-content/uploads/2024/11/20241127-005-png.webp)
![マクロ実行後のディレクトリ](https://jitsuyogaku.com/wp-content/uploads/2024/11/20241127-002-png.webp)
![](https://jitsuyogaku.com/wp-content/uploads/2024/11/20241127-003-png.webp)
![](https://jitsuyogaku.com/wp-content/uploads/2024/11/20241127-004-png.webp)
![](https://jitsuyogaku.com/wp-content/uploads/2024/04/ポテ-004_20240414131827-リサイズ-1.png)
解説していきます。
コードの全体像の解説
![](https://jitsuyogaku.com/wp-content/uploads/2024/09/P1308861-cropped_resized.png)
概要
このコードは、既存のPDFにテキストや枠線を重ねる処理を実現するものです。中心にあるのは、PDFHandler
というカスタムクラスで、このクラスを利用することで、次のような操作を簡単に行えるようにしています。
- フォントの登録
任意のフォントファイルを読み込み、PDF内で使用できるようにします。これにより、カスタムフォントを活用して独自のデザインを反映できます。 - 新しいPDFレイヤーの作成
テキストとその枠線を含む新規PDFレイヤーを作成し、透明度や位置、回転角度といった細かい設定も反映可能です。 - 既存のPDFへのレイヤー合成
作成したPDFレイヤーを、指定したページや全ページに重ね合わせ、加工したPDFを新しいファイルとして保存します。
使用するライブラリ
reportlab
PDFファイルにテキストや図形を描画するライブラリです。このコードでは、キャンバスオブジェクトを使用してテキストや枠線を描画する役割を担います。PyPDF2
PDFファイルの読み取りや編集を行うライブラリです。このコードでは、既存のPDFファイルに新しいレイヤーを合成するために使用します。
クラス設計の特徴
このコードは、以下の2つの観点を重視して設計しています。
- 柔軟性
描画するテキストの位置、色、サイズ、透明度、回転角度を細かく設定できます。また、全ページまたは特定のページへの適用を選択可能です。 - 効率性
PDF操作の主要なタスク(フォント登録、新しいPDFレイヤーの作成、レイヤーの合成)がモジュール化されており、追加の設定や操作を簡単に拡張できます。
クラス内の各メソッドの使われ方
このコードでは、上部に記述されたメソッドが、その下に記述されたメソッド内で順次呼び出され、処理が進むように設計されています。なお、メソッドとは、クラス内に記述された関数のことを指します。つまり、def
で記述されたブロックのことです。
- register_font
カスタムフォントを登録するメソッドです。指定されたフォントファイルをPDFで使用可能な形式で登録します。他のメソッドでテキストを描画する際に必要です。 - draw_text_with_border
キャンバス上にテキストとその枠線を描画するメソッドです。create_text_layer_for_page
で使用され、テキストの描画と、その周囲に余白を持つ枠線を描画する処理を実行します。 - create_text_layer_for_page
テキストを描画するためのPDFレイヤーを作成するメソッドです。このメソッドでは、register_font
を利用してフォントを登録し、draw_text_with_border
を使用してテキストと枠線を描画します。作成したPDFレイヤーはメモリ内のバイトストリームとして保持されます。 - add_text_layer_to_page
特定のページにテキストを追加するメソッドです。merge_pdfs
内で使用され 、create_text_layer_for_page
を呼び出して新しいテキストレイヤーを作成し、それを既存のPDFページに重ねます。 - get_page_dimensions
PDFページの幅、高さ、回転角度を取得する補助メソッドです。merge_pdfs
内で使用され、ページ情報を取得してテキスト描画時の座標や回転角度の調整に利用されます。 - merge_pdfs
アプリケーション全体の制御を行う主要なメソッドです。このメソッドは、入力PDFを読み込み、各ページにテキストを追加し、結果を新しいPDFとして保存します。他のメソッドを呼び出して処理を分割し、最終的なPDFを出力する役割を担います。
想定される利用シーン
このコードは、次のようシーンで活用できます。
- 書類に電子的にスタンプを押す
「参考」や「承認済み」といったスタンプを透かし付きでPDFに追加することができます。 - PDFに注釈を追加する
PDFの特定の位置にコメントやメモを追加することができます。 - カスタムPDFの生成
新しいテキストやデザインを加えたPDFを作成すことができます。
コードの詳細な解説
![](https://jitsuyogaku.com/wp-content/uploads/2024/04/わかりやすく解説_20241011-1024x538.webp)
ここから、コードの解詳細な説をしていきます。
# 標準ライブラリのインポート
import io # バイトストリームを扱うために使用
# 外部ライブラリのインポート
from reportlab.pdfgen.canvas import Canvas # PDFの描画を行うためのモジュール
from reportlab.lib.colors import Color # 色を扱うためのモジュール
from reportlab.pdfbase.ttfonts import TTFont # TrueTypeフォントを使用するためのモジュール
from reportlab.pdfbase import pdfmetrics # フォントの登録やメトリクスを扱うためのモジュール
import PyPDF2 # PDFの読み書きを行うためのモジュール
ここでは、このコードで使用するライブラリをインストールしています。各ライブラリの役割は下表の通りです。
ことばの意味
- ライブラリ
特定の機能をもったコードの集合体です。ソフトウェア作成における部品のようなものです。新しいアプリケーションを作成する際、ライブラリを使用することで、プログラマーは複雑なコードを自分で書く必要がなくなります。 - 外部ライブラリ
Pythonの標準ライブラリに含まれていないライブラリです。外部ライブラリを使うためにはインストールをする必要があります。
ライブラリ | 役割 | 主な使用箇所 |
---|---|---|
import io |
メモリ内でファイル操作を行うためのモジュールです。 | 一時的に新しいPDFデータを保持するBytesIO オブジェクトの作成に使用します。 |
from reportlab.pdfgen.canvas import Canvas |
PDFの描画領域(キャンバス)を作成します。テキストや図形を描画することが可能です。 | 新しいPDFレイヤーを作成し、テキストや枠線、図形などを描画する際に使用します。 |
from reportlab.lib.colors import Color |
RGB値や透明度を設定して色を指定します。 | テキストや枠線の色、透明度を設定する際に使用します。 |
from reportlab.pdfbase.ttfonts import TTFont |
TrueTypeフォントを登録します。 | カスタムフォント(例: YuGothB)をPDFで使用可能にするために登録する際に使用します。 |
from reportlab.pdfbase import pdfmetrics |
フォントの登録やメトリクス(文字幅の計算)を提供します。 | テキストの幅を計算して、枠線や描画位置を調整する際に使用します。 |
import PyPDF2 |
PDFの読み取り、編集、合成、出力を行います。 | 既存のPDFファイルを読み込んだり、新しいレイヤーを重ねたり、編集済みPDFを保存する際に使用します。 |
このように、reportlab
は新しいPDFの描画を、PyPDF2
は既存PDFの編集を担当しています。それぞれの役割を組み合わせることで、PDFにテキストや枠線を簡単に追加できる仕組みを構築しています。
なお、コマンドプロンプトにて外部ライブラリをインストールする方法については、こちらの記事で解説しております。もしよろしければ、合わせてご覧ください。
PyhonのIDLE(Pythonに付属している標準の統合開発環境)ではなく、サードパーティー製の統合開発環境(IDE: Integrated Development Environment)を使用している場合は、その統合開発環境に外部ライブラリをインストールする機能があります。例えば、筆者が使用しているPyCharmでは、コード作成画面にカーソルを置いて「Ctrl + Alt+ S」を押すと次のような外部ライブラリインストールのダイアログが表示されるので、コマンドではなく「+」ボタンからGUIで外部ライブラリをインストールすることができます。
ことばの意味
- 統合開発環境
プログラムを作成・実行するために必要なソフトウェアやツールが揃っている環境のことです。
![](https://jitsuyogaku.com/wp-content/uploads/2024/11/20241127-007-編集済み-1024x762.webp)
![](https://jitsuyogaku.com/wp-content/uploads/2024/11/20241127-006-編集済み2-1024x765.webp)
なお、PyCharmは筆者の愛読書「独学プログラマー」の著者が、自身が使用している統合開発環境として紹介しています。もしよろしければ、合わせてご覧ください。
class PDFHandler:
"""
PDFの作成、および既存のPDFにテキストを重ねる処理を行うクラス。
主な機能:
- フォントを登録する
- 新しいPDFレイヤーを作成する
- 新しいPDFレイヤーにテキストを描画する
- テキストを描画したPDFレイヤーと既存のPDFを重ねる
"""
def __init__(self, source_pdf_path, destination_pdf_path, font_file_path):
"""
クラスを初期化し、入力PDF、出力PDF、フォントのパスを設定する。
:param source_pdf_path: 入力用のPDFファイルパス
:param destination_pdf_path: 出力用のPDFファイルパス
:param font_file_path: フォントファイルのパス
"""
self.source_pdf_path = source_pdf_path # 入力元のPDFファイルパスを記憶
self.destination_pdf_path = destination_pdf_path # 出力先のPDFファイルパスを記憶
self.font_file_path = font_file_path # フォントファイルのパスを記憶
ここでは、PDFの操作を簡潔にまとめるためのクラス PDFHandler
が定義されています。このクラスは、PDFの作成や既存のPDFにテキストを重ねるための一連の処理を提供します。
クラスの冒頭に記載されたドキュメンテーション文字列(docstring)では、このクラスの主な機能が示されています。
続いて、クラスの初期化部分(「コンストラクタ」となる init メソッド)では、入力PDF、出力PDF、フォントのパスを指定します。これにより、クラス全体でこれらの設定を共有し、各処理で一貫して利用できるようにしています。
def register_font(self, font_name):
"""
フォントを登録する。
:param font_name: 登録するフォントの名前
"""
pdfmetrics.registerFont(TTFont(font_name, self.font_file_path)) # フォントをReportLabに登録
ここでは、PDFで使用するフォントを登録するためのメソッド register_font
を定義しています。このメソッドを使うことで、カスタムフォントをPDF内で利用可能にします。
具体的には、font_name
を引数として受け取り、ReportLabのフォント管理システムに登録します。内部では、TTFont
を用いてフォントファイル(self.font_file_path
)を読み込み、pdfmetrics.registerFont
を呼び出すことで登録を完了します。
これにより、テキスト描画時に登録したフォント名を指定するだけで、PDFにカスタムフォントを反映できるようになります。たとえば、「YuGothB」などの名前でフォントを登録することが可能です。
@staticmethod
def draw_text_with_border(canvas_obj, content, font_name, font_size,
font_color, text_padding, transparency):
"""
キャンバスにテキストとその周囲の枠線を描画する。
:param canvas_obj: ReportLabのCanvasオブジェクト
:param content: 描画するテキスト
:param font_name: フォントの名前
:param font_size: フォントサイズ
:param font_color: テキストと枠線の色(RGBタプル)
:param text_padding: テキストと枠線間の余白
:param transparency: テキストと枠線の透明度(0.0〜1.0)
"""
# 色と透明度を設定
text_color = Color(
font_color[0] / 255.0, # 赤色の値を0〜1に正規化
font_color[1] / 255.0, # 緑色の値を0〜1に正規化
font_color[2] / 255.0, # 青色の値を0〜1に正規化
alpha=transparency # 透明度を設定
)
canvas_obj.setFillColor(text_color) # テキストの塗りつぶし色を設定
canvas_obj.setStrokeColor(text_color) # 枠線の色を設定
canvas_obj.setStrokeColor(text_color) # 枠線の色を設定
canvas_obj.setFont(font_name, font_size) # フォントとサイズを設定
# テキストの描画
canvas_obj.drawString(0, 0, content) # 原点(0,0)にテキストを描画
# 枠線の描画
text_width = pdfmetrics.stringWidth(content, font_name, font_size) # テキストの幅を計算
text_height = font_size # テキストの高さはフォントサイズと同じ
canvas_obj.setLineWidth(1) # 枠線の太さを設定
canvas_obj.rect(
-text_padding, # 左側の余白
-text_padding, # 下側の余白
text_width + 2 * text_padding, # 枠線の幅
text_height + 2 * text_padding # 枠線の高さ
)
ここでは、キャンバス上にテキストとその周囲の枠線を描画するためのメソッド draw_text_with_border
を定義しています。このメソッドは @staticmethod
として定義されており、クラスのインスタンスを必要とせずに汎用的に利用できます。
このメソッドは、指定されたフォントや色でテキストを描画し、そのテキストを囲む枠線を描画します。また、透明度や余白といった細かい調整も可能で、PDFのデザインを柔軟に制御するための基本機能を提供しています。
引数の詳細は、下表の通りです。
引数 | 説明 |
---|---|
canvas_obj |
ReportLabのCanvasオブジェクトを指定します。描画の基盤となるキャンバスです。 |
content |
描画するテキスト内容を指定します。 |
font_name |
テキスト描画に使用するフォントの名前を指定します。 |
font_size |
テキストのフォントサイズを指定します。 |
font_color |
テキストと枠線の色をRGB値(0~255)で指定します。 |
text_padding |
枠線とテキストの間の余白を指定します。 |
transparency |
テキストと枠線の透明度を指定します(0.0~1.0の範囲)。 |
処理の流れは次のようになっています。
- 描画色と透明度の設定
RGB値を0〜1の範囲に変換し、透明度を反映させた色を設定します。 - テキストの描画
指定されたフォントとサイズでキャンバス上にテキストを描画します。 - 枠線の描画
テキストの幅を計算し、その幅と高さに余白(text_padding
)を加えた矩形を描画します。
def create_text_layer_for_page(self, content, font_name, font_size, font_color,
text_x, text_y, text_padding, page_width, page_height,
text_rotation_angle=0, transparency=0.5):
"""
指定したテキストを含むPDFのページを作成する。
:param content: 描画するテキスト
:param font_name: フォントの名前
:param font_size: フォントサイズ
:param font_color: テキストと枠線の色(RGBタプル)
:param text_x: 描画位置のX座標
:param text_y: 描画位置のY座標
:param text_padding: テキストと枠線間の余白
:param page_width: ページの幅
:param page_height: ページの高さ
:param text_rotation_angle: テキストの回転角度(度単位)
:param transparency: テキストと枠線の透明度(0.0〜1.0)
:return: 作成したPDFページを含むBytesIOオブジェクト
"""
self.register_font(font_name) # フォントを登録
packet = io.BytesIO() # バイナリストリームを作成(メモリ内でPDFデータを一時的に保存)
canvas_obj = Canvas(packet, pagesize=(page_width, page_height)) # キャンバスを作成
canvas_obj.saveState() # キャンバスの現在の状態を保存
try:
canvas_obj.translate(text_x, text_y) # 描画位置に移動
canvas_obj.rotate(text_rotation_angle) # テキストを回転
self.draw_text_with_border( # テキストと枠線を描画
canvas_obj, content, font_name, font_size,
font_color, text_padding, transparency
)
except Exception as e:
raise RuntimeError(f"Failed to draw text or border: {e}") # エラーが発生した場合
finally:
canvas_obj.restoreState() # キャンバスの状態を復元する。
# ここで復元されるのは座標系や色、フォント設定などの状態であり、
# すでに描画された内容(テキストや図形)は消えない。
canvas_obj.showPage() # ページの描画を確定
canvas_obj.save() # PDFを保存
packet.seek(0) # バイナリストリームの先頭に戻す(後続の処理で読み込むため)
return packet # 作成したPDFページを含むバイナリストリームを返す
ここでは、指定したテキストを描画する新しいPDFレイヤーを生成するためのメソッド create_text_layer_for_page
を定義しています。このメソッドは、指定されたテキストを描画した単一のPDFページを作成し、メモリ内で保持します。生成されたPDFは、後続の処理で既存のPDFに重ねて使用されます。
ことばの意味
- メソッド
クラスの一部として定義される関数で、特定のオブジェクトに関連する処理や操作を行います。オブジェクトの状態を変更したり、その情報を基に動作を実行します。 - オブジェクト
プログラムで「何かを表現するための具体的な実体」です。データ(プロパティ)と動作(メソッド)を持ち、これらを組み合わせることで、複雑なシステムを柔軟に設計できます。 - バイナリデータ
コンピュータが処理する0と1の組み合わせで表現されたデータのことです。画像やPDFなどのファイル形式も含まれ、人間が視覚的に認識できる形に変換される前のコンピュータ内部での表現形式を指します。 - バイナリストリーム
画像や音声、動画、PDFなどのバイナリデータをビットやバイト単位で連続的に処理する仕組みを指します。例えば、PDFファイルを読み込む際、一括でメモリに読み込むのではなく、順番に少しずつデータを処理する際に利用されます。
引数の詳細は下表の通りです。
引数名 | 解説 |
---|---|
content |
描画するテキストを指定します。 |
font_name |
使用するフォントの名前を指定します(事前に登録されている必要があります)。 |
font_size |
テキストのフォントサイズを指定します。 |
font_color |
テキストと枠線の色をRGB形式(タプル)で指定します(例: (255, 0, 0) )。 |
text_x |
描画位置のX座標(左上原点)を指定します。 |
text_y |
描画位置のY座標(左上原点)を指定します。 |
text_padding |
テキストと枠線の間に設ける余白の幅を指定します。 |
page_width |
PDFページの幅を指定します。 |
page_height |
PDFページの高さを指定します。 |
text_rotation_angle |
テキストを回転させる角度(度単位)を指定します(デフォルトは0)。 |
transparency |
テキストと枠線の透明度を指定します(0.0~1.0、デフォルトは0.5)。 |
処理の流れは、次の通りです。
- フォントの登録
register_font
メソッドを呼び出し、指定されたフォントをPDFで使用可能にします。 - キャンバスの作成
io.BytesIO
を使用してメモリ内でPDFデータを保持するストリームを作成し、その後、Canvas
オブジェクトを作成してページサイズを指定し、キャンバスを初期化します。 - キャンバス状態の保存
saveState
メソッドを使用して現在のキャンバス状態を保存します。この操作により、その後の変更があっても状態を復元可能になります。 - テキストの描画
描画位置をtranslate
メソッドで指定し、rotate
メソッドを使って指定された角度分テキストを回転させます。その後、draw_text_with_border
メソッドを呼び出して、テキストとその枠線を描画します。 - エラーハンドリング
描画中にエラーが発生した場合、例外を発生させて原因を明示します。 - キャンバス状態の復元
restoreState
メソッドを使用して、saveState
メソッドで保存されたキャンバスの設定(座標系、色、フォントなど)を元に戻します。これにより、描画位置や回転などの変更をリセットできますが、すでに描画された内容はそのまま保持されます。 - ページの確定と保存
showPage
メソッドで現在のページを確定し、次にsave
メソッドを使用してPDFデータをバイトストリームに書き込みます。 - ストリームのリセット
seek(0)
を使用してストリームの位置を先頭に戻します。 - 結果の返却
作成されたPDFデータを保持するBytesIO
オブジェクトを返します。
このメソッドは、PDFに追加する要素を柔軟にカスタマイズし、複数ページや異なるレイアウトのPDF編集に対応するための基本的な仕組みを提供しています。
@staticmethod
def get_page_dimensions(page):
"""
ページの幅、高さ、回転角度を取得する。
:param page: PyPDF2のページオブジェクト
:return: (幅, 高さ, 回転角度)のタプル
"""
rotation = page.get("/Rotate", 0) # 回転角度を取得(デフォルトは0)
rotation = rotation % 360 # 回転角度を0〜359度に正規化
media_box = page.mediabox # ページのサイズ情報を取得
width = float(media_box.width) # ページの幅を取得
height = float(media_box.height) # ページの高さを取得
return width, height, rotation # 幅、高さ、回転角度を返す
ここでは、PDFのページサイズと回転角度を取得するための静的メソッド get_page_dimensions
を定義しています。このメソッドは、PyPDF2
のページオブジェクトを入力として受け取り、ページの幅、高さ、回転角度を取得して返します。
このメソッドは、PDFページのレイアウトを動的に調整するために必要な基本的な情報(幅、高さ、回転角度)を提供します。取得した情報は、テキストや枠線の描画位置を正確に決定するために利用されます。
引数の詳細は、下表の通りです。
引数 | 説明 |
page |
PyPDF2 のページオブジェクトを指定します。このオブジェクトは、対象とするPDFのページを指します。 |
戻り値の詳細は、下表の通りです。
戻り値 | 説明 |
---|---|
width | ページの幅(浮動小数点数で返されます)。 |
height | ページの高さ(浮動小数点数で返されます)。 |
rotation | ページの回転角度(0~359度の範囲で正規化されて返されます)。 |
主要な処理の流れは、次の通りです。
- 回転角度の取得
ページオブジェクトから/Rotate
キーを取得し、ページの回転角度を取得します。回転角度が指定されていない場合は、デフォルト値として0を使用します。 - 回転角度の正規化
回転角度を360で割った余りを計算(剰余演算)し、0~359度の範囲に収めます。これにより、負の回転角度や360度以上の値が調整されます。 - ページサイズの取得
ページオブジェクトのmediabox
プロパティから、ページの幅と高さを取得します。このプロパティはPDFページのサイズ情報を含んでいます。 - 幅と高さの計算
mediabox.width
とmediabox.height
を浮動小数点数に変換し、ページの幅と高さを計算します。 - 結果の返却
幅、高さ、正規化された回転角度をタプル形式で返します。この情報は、描画位置や座標計算に使用されます。
このメソッドは、PDFのページ構造を正確に把握するための基盤を提供します。特に、異なるページサイズや回転方向を持つPDFを扱う際に役立ちます。
def add_text_layer_to_page(self, page, content, font_name, font_size,
font_color, text_x, text_y, text_padding,
text_rotation_angle, transparency,
page_width, page_height):
"""
既存のPDFページにテキストレイヤーを重ねる。
:param page: PyPDF2のページオブジェクト
:param content: 描画するテキスト
:param font_name: フォントの名前
:param font_size: フォントサイズ
:param font_color: テキストと枠線の色(RGBタプル)
:param text_x: 描画位置のX座標
:param text_y: 描画位置のY座標
:param text_padding: テキストと枠線間の余白
:param text_rotation_angle: テキストの回転角度(度単位)
:param transparency: テキストと枠線の透明度(0.0〜1.0)
:param page_width: ページの幅
:param page_height: ページの高さ
"""
# 新しいテキストレイヤーを作成
text_layer_pdf = self.create_text_layer_for_page(
content, font_name, font_size, font_color,
text_x, text_y, text_padding, page_width, page_height,
text_rotation_angle, transparency
)
text_layer_reader = PyPDF2.PdfReader(text_layer_pdf) # テキストレイヤーを読み込む
text_page = text_layer_reader.pages[0] # 最初のページを取得
page.merge_page(text_page) # テキストレイヤーを既存のページに重ねる
ここでは、既存のPDFの特定のページにテキストレイヤーを追加するためのメソッド add_text_layer_to_page
を定義しています。このメソッドは、新しいPDFレイヤーを生成し、それを指定された既存のページに重ね合わせる処理を行います。
このメソッドは、事前に指定されたフォントや色、座標を基にテキストレイヤーを作成し、それを既存のPDFページに統合することで、動的なPDF編集を可能にします。
引数の詳細は、下表の通りです。
引数 | 説明 |
---|---|
page |
PyPDF2 のページオブジェクトです。既存のPDFページを指します。 |
content |
描画するテキストです。 |
font_name |
使用するフォントの名前です。 |
font_size |
テキストのフォントサイズです。 |
font_color |
テキストと枠線の色をRGBタプル(例: (255, 0, 0) )で指定します。 |
text_x |
テキストを描画するX座標です。 |
text_y |
テキストを描画するY座標です。 |
text_padding |
テキストと枠線間の余白を指定する値です。 |
text_rotation_angle |
テキストの回転角度を指定します。 |
transparency |
テキストと枠線の透明度(0.0〜1.0)を指定します。 |
page_width |
ページの幅です。 |
page_height |
ページの高さです。 |
戻り値はありませんが、引数として受け取った page
オブジェクトにテキストレイヤーが統合されます。
処理の流れは、次の通りです。
- 新しいPDFレイヤーの生成
create_text_layer_for_page
メソッドを使用して、新しいPDFレイヤーを生成します。このレイヤーには、指定されたテキストやフォント設定が反映されます。 - PDFレイヤーの読み込み
生成されたPDFレイヤーをPyPDF2.PdfReader
を使って読み込みます。このステップでは、PDFレイヤーの内容が操作可能なオブジェクトとして取得されます。 - ページの取得
読み込んだPDFレイヤーの最初のページを取得します。このページが、既存のPDFに重ねるためのレイヤーとして利用されます。 - 既存ページへのレイヤー統合
取得したページオブジェクトを用いて、page.merge_page
を呼び出し、既存のPDFページに新しいレイヤーを重ね合わせます。
このメソッドを使うことで、既存のPDFに対して動的にテキストを追加できます。
def merge_pdfs(self, content, font_name='CustomFonts', font_size=12,
font_color=(0, 0, 0), text_x=0, text_y=0, text_padding=10,
specific_page=None, apply_to_all_pages=False,
text_rotation_angle=0, transparency=0.5):
"""
既存のPDFにテキストを重ね、新しいPDFを作成する。
:param content: 追加するテキスト
:param font_name: フォントの名前
:param font_size: フォントサイズ
:param font_color: テキストと枠線の色(RGBタプル)
:param text_x: 描画位置のX座標(左上原点)
:param text_y: 描画位置のY座標(左上原点)
:param text_padding: テキストと枠線間の余白
:param specific_page: テキストを追加する特定のページ番号(0基準)。
apply_to_all_pages が True の場合、この値は無視される。
:param apply_to_all_pages: 全ページに適用するか(Trueなら全ページ)
:param text_rotation_angle: テキストの回転角度(度単位)
:param transparency: テキストと枠線の透明度(0.0〜1.0)
"""
with open(self.source_pdf_path, "rb") as f_input:
reader = PyPDF2.PdfReader(f_input) # 入力PDFを読み込む
writer = PyPDF2.PdfWriter() # 出力PDFのライターを作成
# PDFの各ページを処理
for i, page in enumerate(reader.pages):
# ページの幅、高さ、回転角度を取得
page_width, page_height, rotation = self.get_page_dimensions(page)
# 対象ページかどうかを判定
if apply_to_all_pages or (specific_page is not None and i == specific_page):
rotation = rotation % 360 # 回転角度を正規化
# 回転角度に応じて座標と回転を調整
if rotation == 0:
adjusted_x = text_x
adjusted_y = page_height - text_y - font_size
adjusted_rotation_angle = text_rotation_angle
elif rotation == 90:
adjusted_x = text_y + font_size
adjusted_y = text_x
adjusted_rotation_angle = text_rotation_angle + 90
elif rotation == 180:
adjusted_x = page_width - text_x
adjusted_y = text_y + font_size
adjusted_rotation_angle = text_rotation_angle + 180
elif rotation == 270:
adjusted_x = page_width - text_y - font_size
adjusted_y = page_height - text_x
adjusted_rotation_angle = text_rotation_angle + 270
else:
adjusted_x = text_x
adjusted_y = page_height - text_y - font_size
adjusted_rotation_angle = text_rotation_angle
# テキストレイヤーをページに追加
self.add_text_layer_to_page(
page, content, font_name, font_size,
font_color, adjusted_x, adjusted_y, text_padding,
adjusted_rotation_angle, transparency,
page_width, page_height
)
# ページを出力PDFに追加
writer.add_page(page)
# 出力PDFを保存
with open(self.destination_pdf_path, "wb") as f_output:
writer.write(f_output)
# 処理完了のメッセージを表示
print("Text added to PDF successfully.")
ここでは、既存のPDFに新しいテキストを重ねたPDFを作成(出力)するためのメソッド merge_pdfs
を定義しています。このメソッドは、指定したテキストやフォント設定を基に、新しいPDFを生成し、指定された場所に保存します。これにより、PDF全体や特定のページに対してテキストを追加する編集が可能になります。
引数の詳細は以下の通りです。
引数名 | 説明 |
---|---|
content | 追加するテキストです。 |
font_name | 使用するフォントの名前です。 |
font_size | テキストのフォントサイズです。 |
font_color | テキストと枠線の色です。RGB形式のタプル(例:(255, 0, 0))で表されます。 |
text_x | 描画位置のX座標です。座標は左上原点で計算されます。 |
text_y | 描画位置のY座標です。座標は左上原点で計算されます。 |
text_padding | テキストと枠線間の余白です。単位はポイント(pt)です。 |
specific_page | テキストを追加する特定のページ番号です。0基準の整数で表されます。apply_to_all_pages がTrue の場合は無視されます。 |
apply_to_all_pages | 全てのページにテキストを適用する場合はTrue 、特定のページにのみ適用する場合はFalse です。 |
text_rotation_angle | テキストの回転角度です。単位は度です。 |
transparency | テキストと枠線の透明度です。0.0(完全透明)から1.0(完全不透明)の範囲で指定します。 |
処理の流れは、次の通りです。
- 入力PDFを読み込む
self.source_pdf_path
で指定されたPDFファイルをPyPDF2.PdfReader
を使って開き、変数reader
に格納します。 - 出力PDFライターを作成する
PyPDF2.PdfWriter
をインスタンス化し、変数writer
に格納します。このオブジェクトに新しいページを追加していきます。 - PDFの各ページを処理する
reader.pages
をループで回し、変数page
に各ページのデータを取得します。ループのインデックスはi
に格納されます。 - ページの幅、高さ、回転角度を取得する
メソッドget_page_dimensions
を呼び出して、現在のページの幅、高さ、および回転角度を取得します。これらはpage_width
、page_height
、rotation
に格納されます。 - 対象ページかどうかを判定する
apply_to_all_pages
がTrue
か、またはspecific_page
と現在のページ番号i
が一致する場合に処理を続行します。 - 回転角度に応じて座標と回転角度を調整する
ページの回転角度rotation
に応じて、テキストの座標を調整します。この結果はadjusted_x
、adjusted_y
、adjusted_rotation_angle
に格納されます。 - テキストレイヤーをページに追加する
メソッドadd_text_layer_to_page
を呼び出し、調整後の座標と回転角度を用いてテキストレイヤーをpage
に重ねます。 - 処理したページを出力PDFに追加する
writer.add_page(page)
を呼び出して、処理済みのpage
を出力PDFに追加します。 - 出力PDFを保存する
self.destination_pdf_path
で指定されたパスにファイルを書き出します。これにはwriter.write()
を使用します。 - 処理結果を通知する
標準出力に「Text added to PDF successfully.」を表示して処理が完了したことを通知します。
このメソッドを使用すると、既存のPDFに動的にテキストを追加し、編集結果を実際のファイルとして保存することができます。この機能により、PDF作成と出力の中核を担う重要な役割を果たしています。
def main():
"""
既存のPDFにテキストと枠線を重ねる処理を行う。
この関数では、PDFHandlerクラスを利用して次の処理を実行する:
- 入力PDFと出力PDFの指定
- テキストの内容、位置、フォント、サイズ、透明度の設定
- 指定されたページまたは全ページにテキストを重ねる処理
"""
# PDF編集に必要な設定を指定
source_pdf_path = 'input.pdf' # 入力元のPDFファイルパス
destination_pdf_path = 'output.pdf' # 出力先のPDFファイルパス
content = '参考' # PDFに描画するテキスト
font_size = 22 # テキストのフォントサイズ
font_color = (255, 0, 0) # テキストの色(RGB形式)
font_file_path = 'fonts/YuGothB.ttc' # 使用するフォントファイルのパス
specific_page = 0 # テキストを追加するページ番号(0基準)
# apply_to_all_pages が True の場合、この値は無視される
apply_to_all_pages = True # 全ページに適用するか(Trueなら全ページ)
text_rotation_angle = 5 # テキストの回転角度(度単位)
text_x = 50 # テキスト描画位置のX座標(左上原点)
text_y = 50 # テキスト描画位置のY座標(左上原点)
text_padding=10 # テキストの余白を指定
# PDF操作クラスのインスタンスを作成
pdf_handler = PDFHandler(
source_pdf_path,
destination_pdf_path,
font_file_path
)
# PDFにテキストを重ねる処理を実行
pdf_handler.merge_pdfs(
content, # 追加するテキスト
font_name="YuGothB", # 使用するフォント名
font_size=font_size, # フォントサイズ
font_color=font_color, # フォントの色
text_x=text_x, # テキストのX座標
text_y=text_y, # テキストのY座標
text_padding=text_padding, # テキストの余白を指定
specific_page=specific_page, # 特定のページ番号
apply_to_all_pages=apply_to_all_pages, # 全ページに適用するか
text_rotation_angle=text_rotation_angle, # テキストの回転角度
transparency=0.3 # 透明度
)
ここでは、PDFHandler
クラスを利用して、既存のPDFにテキストと枠線を重ね、新しいPDFファイルとして保存します。編集対象のPDFや追加するテキストに関する各種設定を行い、merge_pdfs メソッドを呼び出すことで処理を実行します。
この関数の役割は次の通りです。
- 入力PDFと出力PDFの指定
編集対象となる入力PDFのパス(source_pdf_path
)と、編集結果を保存する出力PDFのパス(destination_pdf_path
)を設定します。 - テキスト描画のパラメータ指定
テキストの内容(content
)、位置(text_x
とtext_y
)、フォントサイズ(font_size
)、色(font_color
)、透明度(transparency
)など、描画に必要な詳細な設定を行います。 - PDFHandlerのインスタンス作成
指定した入力ファイル、出力ファイル、フォントファイルのパスを基にして、PDFHandler
クラスのインスタンスを作成します。このインスタンスは、PDF編集の主要な処理を担当します。 - PDF編集処理の実行
merge_pdfs
メソッドを呼び出して、PDF全体または特定のページにテキストを追加し、編集済みのPDFを保存します。
設定項目の詳細は下表の通りです。
設定項目 | 説明 |
---|---|
source_pdf_path |
入力元のPDFファイルのパスです。 |
destination_pdf_path |
編集後のPDFを保存する出力ファイルのパスです。 |
content |
PDFに描画するテキストの内容です。 |
font_size |
描画するテキストのフォントサイズです。 |
font_color |
テキストの色をRGB形式で指定します(例: (255, 0, 0) )。 |
font_file_path |
使用するフォントファイルのパスです。 |
specific_page |
編集対象となる特定のページ番号(0基準)を指定します。apply_to_all_pages がTrue の場合は無視されます。 |
apply_to_all_pages |
全てのページにテキストを適用する場合はTrue 、特定ページのみ適用する場合はFalse です。 |
text_rotation_angle |
テキストの回転角度(度単位)です。 |
text_x |
テキストの描画位置を指定するX座標です(左上原点)。 |
text_y |
テキストの描画位置を指定するY座標です(左上原点)。 |
text_padding |
テキストと枠線間の余白を指定します。 |
transparency |
テキストの透明度を0.0(完全透明)から1.0(完全不透明)で指定します。 |
処理の流れは次の通りです。
- 必要なファイルパスとパラメータの指定
source_pdf_path
、destination_pdf_path
、font_file_path
で入力・出力ファイルのパスとフォントファイルを指定します。また、テキスト描画に必要な設定(content
、font_size
、font_color
など)を変数に代入します。 - PDFHandlerのインスタンス作成
設定されたパスとパラメータを基にして、PDFHandler
クラスのインスタンスを生成します。このインスタンスを通じてPDF編集を行います。 - テキストの追加とPDFの保存
merge_pdfs
メソッドを呼び出して、指定されたページまたは全ページにテキストを重ねます。その結果をdestination_pdf_path
で指定したパスに保存します。
この関数を利用すると、既存のPDFに対して動的にテキストを追加し、新しいPDFファイルを簡単に作成できます。設定を変更することで、全ページへの適用やページごとの詳細なカスタマイズも可能です。
if __name__ == "__main__":
main()
ここでは、スクリプトのエントリーポイントを定義しています。if __name__ == "__main__":
という条件式は、Pythonがスクリプトを実行するとき、自動的に設定される特別な変数 __name__
を利用しています。スクリプトが直接実行された場合、この値は "__main__"
に設定されます。そのため、この条件が成立すると、main()
関数が呼び出される仕組みになっています。
この構造により、スクリプトが他のモジュールからインポートされた場合に、main()
関数が実行されることを防ぎます。これは、モジュールの再利用性と独立性を高めるためのPythonにおける一般的なプラクティスです。
この構造によって、スクリプトを直接実行したときにはPDFの編集処理が行われ、他のプログラムからインポートされたときには必要なクラスや関数のみを利用できるようになります。
ことばの意味
- プラクティス
「慣習」「習慣」「推奨される方法」という意味です。ここでは、Pythonプログラミングにおける一般的な慣習やベストプラクティスを指しています。
![](https://jitsuyogaku.com/wp-content/uploads/2024/04/ポテ-004_20240414131827-リサイズ-1.png)
以上で解説は終了です。ありがとうございました。
おわりに
![](https://jitsuyogaku.com/wp-content/uploads/2024/11/P4239668_cropped_resized-png.webp)
![](https://jitsuyogaku.com/wp-content/uploads/2024/04/ポテ-004_20240414131827-リサイズ-1.png)
ご覧いただきありがとうございました。
本稿では、「PDFに電子スタンプを押す方法」を解説いたしました。
お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。
皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。
なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご覧いただけると幸いでございます。
記事関連経験
- Python 3 エンジニア認定基礎試験
経済産業省が定めたガイドライン「ITスキル標準(ITSS)」に掲載されている民間資格です。 - Python 使用経験 約5年
実務に使用する アプリを多数作成してきました。
Python プログラミングスキルアップのための参考情報
ここでは参考図書を紹介いたしますが、これに限らず自分に合うものを選ぶことが重要だと考えております。皆様の、より一層のご成功を心からお祈りしております。
「独学プログラマー」というPythonを題材にした書籍は大変勉強になりました。Pythonの技術解説だけにとどまらず、プログラミングの魅力や基本的な知識、思考法、仕事の進め方まで幅広く学べます。
こちらの記事でも紹介しております。もしよろしければご覧ください。
また、Pythonに関する書籍は多数出版されています。興味のある方は、チェックしてみてください。
\チェックしてみよう/
\チェックしてみよう/
\チェックしてみよう/
![](https://jitsuyogaku.com/wp-content/uploads/2024/06/qrcode_jitsuyogaku.com20240408python-create-menu-with-tabs.png)