Algorithm & UI/UX
クライアントサイドで完結させる
画像PDF変換の最適化戦略
サーバーに一切画像を送信せず、ブラウザのメモリ上だけでPDFを構築する。この「プライバシー第一」の設計を実現するために導入した、メモリ消費を抑える最適化アルゴリズムと、多様な画像サイズをA4に収めるフィッティングロジックについて解説します。
このツールの入力から出力まで
現行コードの確認日:
- 入力
- 順番に並べたい画像を複数選びます。縦長と横長が混ざった入力でも、各画像の幅と高さを使います。
- 処理
- 読み込んだ画像をJPEGへ縮小し、jsPDFで1枚につきA4の1ページを追加します。画像比率を保ってページ中央へ収め、余白を作ります。
- 出力
- 画像ごとに1ページの A4 PDF を作ります。
まず確認する点:一覧の順序がPDFのページ順です。文字の検索性ではなく、生成PDFを拡大したときの細い文字の読みやすさを確認します。
仕上がりの例
猫の写真2枚を、1枚ずつ別ページに配置したPDFの例です。
保存したPDFの2ページを、比較用に並べて表示しています。
掲載画像はサイトにある既存の公開作例です。保存済みの資料では運営者の愛猫の写真を使用しています。今回の確認日が、この作例を実行した日を表すわけではありません。
保存済み検証記録の条件を見る
資料の種類は「ツールの出力画像を保存した記録」です。公開作例と保存済み記録で素材や色などが異なる場合があるため、下の数値は保存済み検証記録の条件として読んでください。
写真2枚を、縦横比を保って1枚ずつ別のA4ページへ最大化。写真の向きに合わせた2ページのPDFを実際に保存し、各ページを表示。
- 記録の入力画像
- 800×667px (JPEG)、800×1066px (JPEG)
- 保存済みPDFを表示した記録画像
- 994×703px (PNG)、703×994px (PNG)
| 画面の項目 | 記録の値 | 現行コードの初期値・範囲 |
|---|---|---|
| 記録のPDFページ数 | 2ページ | — |
資料ファイルの作成日は実行日として扱っていません。個別端末の処理速度や、ほかの写真に対する検出・加工の精度を測定した資料でもありません。
実装の確認箇所:src/pages/image/to-pdf/index.astro。以下のコード抜粋と出力条件は、この本番実装に基づいて説明します。
仕組みを読み進めるときは、async / awaitと並行処理(画像やライブラリの取得を待つ処理の順序)、File APIとObject URL(選んだ画像の読み込みとBlob URLの解放)が参考になります。
1. 2段階の適応型リサイズ・パイプライン
スマホで撮影した写真は1枚数MB〜十数MBに達することがあります。これらをそのまま複数枚読み込むと、ブラウザのメモリが枯渇し、タブがクラッシュする原因となります。
本ツールでは、ファイルを読み込んだ直後に「1段階目の粗いリサイズ」を行い、サムネイル用データの作成時に Canvas を用いて「2段階目の縮小」を行うパイプラインを採用しています。これにより、HEICなどの重い形式も軽量なJPEGに変換され、PDF に埋め込む画像の画素数と容量を減らします。大量の画像を保持するとメモリ不足になる場合があります。
1枚をページ内へ切り取らずに収める計算です。pageWidth・pageHeight の単位は mm を想定します。
function pdfFit(iw, ih, pageWidth, pageHeight) {
const scale = Math.min(pageWidth / iw, pageHeight / ih);
const width = iw * scale, height = ih * scale;
return { x: (pageWidth - width) / 2, y: (pageHeight - height) / 2, width, height };
} 2. アスペクト比を維持する動的センタリング・アルゴリズム
PDF作成時、画像によって向き(縦・横)や比率はバラバラです。本実装では、jsPDFのページ設定を動的に切り替えつつ、A4の枠内に画像を「アスペクト比を維持しながら最大サイズで配置」する計算を行っています。
特に、ページ比率と画像比率を比較し、縦に合わせるか横に合わせるかを分岐させることで、どのような形状の画像でも中央に綺麗にレイアウトされます。
出力の仕様と確認する点
画像ごとに1ページの A4 PDF を作ります。画像の幅が高さより大きければ横向き、それ以外は縦向きです。比率を保ってページ中央に配置するので、画像を切り落とす代わりに余白ができます。
読み込み段階に長辺 2500px の制限があり、一覧に保持する画像はさらに長辺 1500px 以下の JPEG(品質指定 0.8)にします。PDF はこの JPEG を埋め込むため、元画像の画質や寸法をそのまま保つ変換ではありません。
並び順がページ順になります。画像内の文字を認識する OCR はなく、検索・選択できるテキストにはなりません。細い文字の書類は、作成した PDF を拡大して読みやすさを確認してください。
