Node.jsとWASM製ライブラリでPDFからテキスト抽出・画像変換CLIツールのプロトタイプ開発

Tadashi Shigeoka ·  Thu, September 18, 2025

近年、ドキュメントの内容をAIで活用するRAG (Retrieval-Augmented Generation) などの技術が注目されています。その前処理として、PDFファイルからテキストや画像を抽出し、ベクトル化する需要が高まっています。

今回は、この前処理の第一歩として、Node.jsで動作するPDF処理CLIツールをプロトタイプ開発しました。

この記事では、開発の背景、特にWebAssembly (Wasm) を採用した技術選定の理由、そして実装したツールの概要についてご紹介します。

背景:サーバーレスで動かしたい!

最終的な目標は、ユーザーがアップロードしたPDFを処理し、その内容(テキストや画像)をベクトル化してデータベースに保存するWebアプリケーションを構築することです。開発スタックとしては、VercelとNext.jsを想定しています。

ここで課題となるのが、PDF処理ライブラリの依存関係です。多くのPDF処理ライブラリは、popplerImageMagickといったネイティブバイナリに依存しています。これらのバイナリは、Vercelのようなサーバーレス環境では簡単に利用できず、追加のビルド設定や環境の制約が発生しがちです。

そこで、プラットフォームに依存しないWebAssembly (Wasm) でビルドされたライブラリに着目しました。WASMであれば、特別な環境構築なしにNode.jsランタイムで直接実行できるため、サーバーレス環境との相性が抜群です。

技術選定:WASMベースのライブラリ

今回のプロトタイプでは、以下のWASMベースのパッケージを採用しました。

  • @hyzyla/pdfium: GoogleがメンテナンスするPDFレンダリングエンジン「PDFium」のWASMビルドです。PDFの読み込み、テキスト抽出、ページごとのレンダリングなど、強力な機能を提供します。
  • @jsquash/png: 高速な画像コーデックライブラリlibspngをWASM化したものです。PDFiumでレンダリングしたビットマップデータをPNG形式にエンコードするために使用します。

これらのライブラリはnpm installするだけで必要なWASMアセットがダウンロードされ、追加のビルドステップなしで利用できる手軽さも魅力です。

完成したCLIツールの概要

開発したCLIツール pdf-tool は、指定されたPDFファイルに対してテキスト抽出と画像変換を実行できます。

# 基本的な使い方
node ./bin/pdf-tool.mjs <pdf-path> [options]

主な機能は以下の通りです。

  • テキスト抽出:
    • ページごとのテキストをプレーンテキストまたはJSON形式で出力 (--text-out, --text-format)
    • 全ページのテキストを1つのブロックに結合 (--text-join)
  • 画像変換:
    • PDFの各ページを指定したディレクトリにPNG画像として保存 (--png-dir)
    • 出力画像の解像度をスケールやピクセルサイズで指定 (--scale, --width, --height)
  • その他:
    • 処理対象のページを指定(例: 1,3-5) (--pages)
    • パスワードで暗号化されたPDFにも対応 (--password)

使い方と実行例

いくつか具体的なコマンド例を見てみましょう。

例1: テキストをJSONで、画像を2倍スケールで出力

1〜3ページ目を対象に、テキストをJSON形式で output/sample.json に、ページ画像を2倍の解像度で output/images/ ディレクトリに出力します。

node ./bin/pdf-tool.mjs ./docs/sample.pdf \
  --pages 1-3 \
  --text-out output/sample.json \
  --text-format json \
  --png-dir output/images \
  --scale 2

例2: 全ページのテキストを1つのファイルにまとめる

PDF内のすべてのテキストを抽出し、改ページを無視して1つのテキストファイルとして保存します。LLMへの入力データ作成などに便利です。

node ./bin/pdf-tool.mjs ./docs/sample.pdf --text-out output/sample.txt --text-join

プロジェクト構成

ソースコードは機能ごとにモジュール化しています。

  • src/pdfium/: PDFiumの初期化やドキュメント読み込みに関するヘルパー関数
  • src/text/: テキスト抽出処理のロジック
  • src/image/: ページのレンダリングとPNGエンコード処理のロジック
  • bin/pdf-tool.mjs: 上記モジュールを束ね、コマンドライン引数を解釈するエントリーポイント

このように関心を分離することで、将来的にNext.jsのAPI Routesなどに機能を移植しやすくなります。

まとめと今後の展望

今回は、Vercel + Next.js環境での利用を見据え、WASMベースのライブラリを活用してPDF処理CLIツールのプロトタイプを開発しました。これにより、環境依存を気にすることなく、堅牢なPDF前処理基盤の実現可能性を確認できました。

今後は、このプロトタイプをベースに、

  • Next.jsのAPI Routesに処理を組み込み、Web APIとして提供する
  • 抽出したテキストや画像をベクトル化し、ベクトルデータベースに保存する

といった機能拡張を進めていく予定です。

WASMのおかげで、これまでサーバーサイドで扱いにくかった処理も、JavaScript/Node.jsエコシステムの中で完結させられるようになり、開発の幅が大きく広がったと感じます。

以上、現場からお送りしました。

参考情報