PerfectVector
著者: Irene Kim2 分で読める

fpdf2のSVG画像:PythonのPDFでパスを保つ

fpdf2でPythonのPDFにSVGロゴを配置し、サイズと保存したパスを確認します。ラスターへの代替を選ぶ前に、欠ける文字や形状を診断します。

目次

pdf.image("logo.svg", x=20, y=20, w=60) を使うと、fpdf2文書にSVGを配置できます。対応するSVG形状はPDFの描画パスになります。先にロゴをPNGに描画する必要はありません。公式のSVGドキュメントでは、この直接の方法と制限を説明しています。

形式自体に不慣れな場合は、SVGファイルガイドがパスと画像コンテナーを説明しています。読み込みが成功しても確認は必要です。ファイルには埋め込みピクセル、読み込み側で再現しない機能、図形の周囲の余白がある場合があります。このガイドでは、小さなオリジナルロゴを作り、サイズを明示して配置し、出来上がったPDFを確認します。既存のベクターマスターがあれば保持してください。PNGやJPGからの図形復元は、それより前の別工程です。

既知のSVGと固定したfpdf2バージョンから始める

この例はPython 3.12と fpdf2 2.8.8 で実行しました。テストしたバージョンであり、それ以降のすべての版が同じように動くという約束ではありません。公式PyPIページでは、配布名 fpdf2 でのインストールを説明しています。Pythonのimport名は fpdf です。

別プロジェクトのパッケージに依存しないよう、新しい環境を使います。

python3 -m venv .venv
source .venv/bin/activate
python -m pip install "fpdf2==2.8.8"

Windowsでは代わりに .venv\Scripts\activate で環境を有効にします。次のオリジナルの長方形の紋章を logo.svg として保存してください。

<svg xmlns="http://www.w3.org/2000/svg"
     width="120" height="80" viewBox="0 0 120 80">
  <path fill="#137d89" fill-rule="evenodd"
        d="M10 10H110V70H10Z M30 25H90V55H30Z"/>
</svg>

閉じたサブパスが2つあります。外側の長方形が塗られ、内側は evenodd の塗り規則で開口部になります。フォント、画像、効果を使わないので、最初のテストを診断しやすくなっています。

次をSVGと同じ場所に place_logo.py として保存します。

from pathlib import Path
from fpdf import FPDF
 
folder = Path(__file__).resolve().parent
pdf = FPDF(unit="mm")
pdf.add_page()
pdf.image(str(folder / "logo.svg"), x=20, y=20, w=60)
pdf.output(str(folder / "logo.pdf"))

python place_logo.py を実行します。logo.pdf を開き、左上近くの青緑色の長方形の枠と、中央から見えるページを確認してください。

SVGのキャンバスと色が付いたロゴを区別する

元のキャンバスの比率は3:2で、幅120、高さ80単位です。w=60 では、この例の キャンバスは60 × 40 mm になります。図形はキャンバスの内側10単位から始まるため、色が付いた外側の長方形は 50 × 30 mm で、ページ上の 25, 25 mm から始まります。これらは今回の座標と縮尺からの計算です。

この余白があるため、色付き形状の測定値は配置キャンバスの測定値と一致しません。顧客のロゴが小さく見える場合は、PDFでの幅を増やす前に元の余白を確認してください。

fpdf2の画像ガイドでは、寸法の扱いと、指定した枠内で比率を保つ選択肢を説明しています。この最初の例では幅だけを設定します。後で両方の寸法を指定するなら、すべての元データの比率が同じと思わず、必要な収まり方を意図的にテストしてください。

大きなキャンバス内の長方形ロゴと、それを文書ページに配置する様子のイラスト
配置キャンバスには図形周囲の余白も含まれます。このイラストは2つの境界を説明するものです。実際の寸法は書き出したPDFで確認してください。

保存したPDFがパスを含むことを確認する

PDFプレビューは見た目を示しますが、画像もほどほどの拡大率なら鮮明に見えます。ファイルも確認してください。この独立した例は pypdf 6.1.1 で検証しました。

python -m pip install "pypdf==6.1.1"
from pathlib import Path
from pypdf import PdfReader
 
folder = Path(__file__).resolve().parent
page = PdfReader(folder / "logo.pdf").pages[0]
print("Page images:", len(page.images))
print(page.get_contents().get_data().decode("latin-1"))

出力は ページ画像0個 と報告しました。復号した内容には、移動、直線、パスを閉じる操作で表された長方形の輪郭があり、その後に偶奇塗り操作の f* がありました。描画された開口部と合わせ、この画像なしの例が保存したPDFでも描画形状のままだったと判断できます。

確認せずに別の入力へこの結論を適用しないでください。レポートの別の場所に写真があるのは正当で、SVG自体にも画像を含められます。埋め込みラスターの診断は、パスのロゴとSVGで包んだビットマップを区別するのに役立ちます。より複雑なPDFは参照オブジェクト内にも描画内容を置く場合があるため、上の短いスクリプトは独立したこの例の開始点であり、万能のPDF監査ではありません。

インストール済みの版で図形の欠落を診断する

まず上の小さな紋章を実行してください。それが動いて本番ロゴだけが失敗するなら、問題を元の図形や使用機能に絞れます。原本を保持し、コピーを1機能ずつ単純化します。

症状最初の確認有用な次の工程
ページが空白ファイルパス、配置、寸法、読み込みの警告明示的な座標で単純な紋章をテストする
ロゴが小さく見える元のキャンバス内の余白描画境界をviewBoxと比較する
中央が埋まる複合パス構造と塗り規則編集や書き出しで開口部を保持する
文字が欠けたり違ったりするインストール済みの版、フォント選択、文字機能別の文字サンプルをテストするか、承認済みのアウトライン文字を使う
装飾が消える非対応のSVG機能コピーからその機能を除いて結果を比較する
PDFは鮮明だがピクセルを含むかもしれない元データとPDFの埋め込み画像プレビューとともにファイル構造を確認する

古い回答には注意が必要です。別途行った2.8.8の簡単な <text> 要素の検証では、抽出可能な HELLO の文字が生成され、基本的な線形グラデーションの長方形も正常に書き出せました。この限定した確認は、SVGの文字、フォント、CSS、グラデーションの完全な互換性を示しません。ただし、SVGの文字やグラデーションはすべて非対応だという古い記述が、不要なラスター化につながり得る理由を示します。

現在のSVG機能一覧にも、マーカー、パターン、パス上の文字、複雑なCSSや外部CSSなどの制限が挙がっています。診断中は読み込みの警告を見えるようにし、保存したページを元データと比較してください。ログに問題がないだけでは、すべての視覚機能が残った証明にはなりません。

結果に応じてラスターへの代替を使う

選んだ処理で効果を再現できない場合、形状の保持より見た目の保持が重要かを判断します。その文書の部分には、描画したPNGが適する場合があります。最終的な物理サイズで確認し、出力を正確に説明してください。ラスター描画を埋め込んでも、元のパスは保持されません。

ブランドロゴには、承認されたアウトライン文字や単純なベクター書き出しの方が良い場合があります。文書の文字を編集可能なまま保つには、フォントとテキストを文書作成の工程で扱ってください。文章のスクリーンショットをトレースしても、書体は復元されず、選択できる文字にもなりません。

既存のPDFコードが別のPythonライブラリーを使っている場合は、ReportLabのSVG手順に独自の読み込みとサイズ確認があります。ライブラリー変更は別の実装判断なので、文書を作り直す前に、実際に問題になった機能をテストしてください。

PDF工程の前にラスターだけの図形を準備する

PNGやJPGのロゴしか残っていない場合、fpdf2に読み込む前にPerfectVectorのロゴベクター化ツールでSVG候補を作れます。輪郭、小さな開口部、色領域を元画像と比較し、同じ配置とPDFの確認を行ってください。

元のベクターがあれば使います。正確なブランド文字には打ち直しや手動修正が必要な場合があり、ロゴベクター化ガイドではその選択を説明しています。この記事の紋章はオリジナルの手書きSVGで、PerfectVectorの変換結果を測定したものではありません。PerfectVectorは図形を準備し、fpdf2はPDF内での配置を制御します。

よくある質問

fpdf2はSVGを直接挿入できますか? はい。SVGファイルをimageメソッドに渡し、配置とサイズを設定します。対応する形状はPDFのパスになりますが、自分の図形について書き出したファイルと見た目を確認してください。

fpdf2はSVGの文字に対応していますか? 今回の基本的な文字の検証はfpdf2 2.8.8で動きました。ただし、すべてのフォント、レイアウト機能、パス上の文字を保証しません。インストール済みの版を確認し、文書が実際に使う文字をテストしてください。

60 mmの画像が60 mmより狭く見えるのはなぜですか? 指定したサイズは配置キャンバスに適用されます。SVG内部の余白もそのキャンバスの一部なので、色付きの形状はそれより狭くなる場合があります。

追加する前にPNGロゴをSVGに変換すべきですか? 編集可能なパスが必要で、図形がトレースに適する場合だけです。写真はラスター画像として保持し、元のベクターロゴがあれば使ってください。トレースの候補は挿入前に確認します。

参考資料

  1. fpdf2 — SVG — SVGの直接挿入、機能対応、警告ログを説明しています。
  2. fpdf2 — 画像 — 画像の配置、寸法、縦横比を保つ収め方を説明しています。
  3. fpdf2 — PyPIパッケージ — インストール可能な配布パッケージとPythonのimport規則を示しています。

ラスターのロゴしかない場合は、PerfectVectorでSVG候補を作成し、輪郭と開口部を確認してください。その後、fpdf2で必要なサイズに配置し、保存したPDFを確認します。

ブログのその他の記事

編集しやすい
よりきれいなSVGから始めましょう