◆ PDFJS ドキュメント少なすぎ
◆ サンプルコピペだと cmap のエラーがでてた
  ◆ cmaps フォルダへのパスが必要

PDF を画像ファイルにして扱いたかったので PDFJS を使ってみました

PDFJS

サイズ大きすぎて minify できなーい って記事だけ書くはずだったのに 思った以上に PDFJS の説明部分が長くなったので記事を分けてみました (続き)

PDFJS は もともと mozilla が作った Firefox 用の JavaScript で PDF レンダリングするライブラリだったはずがいつのまにか Chrome でも使われてました
PDF ページ開いて devtools を表示して ロードされてる JavaScript を確認するとわかります


使うにはまず公式サイトからダウンロードします
https://mozilla.github.io/pdf.js/

ソースからビルドするか Pre-build というビルドしてくれてるのがあります
JavaScript なのでビルドもそこまで手間はなさそうですが ビルド済みがあるならそっちを使うほうが楽です


使ってみて思ったのですが Firefox にも Chrome にも使われていて重要なライブラリのはずなのにドキュメントがなさすぎです
メニューの API を選んでもほとんど書かれていなくて ググってみても ソースがドキュメントみたいな感じでした

最低限の表示なら Examples の通りで出来ると思ったら 日本語が表示されなくて真っ白だったりと苦戦されられました

使い方

ダウンロードしたものは build と web のフォルダにわかれていて web の方は ビュワーが入ってるので こっちはいらないように思いますが 一部使います

必要なのは
  • build/pdf.js
  • build/pdf.worker.js
  • web/cmaps/

です

IE の 8 とか 10 とかにも対応させるなら compatibility.js を先にロードさせておきます
polyfill が入ってます

compatibility.js 以外は pdf.js のみのロードで大丈夫です
worker 等は自動で読みこまれます

ただ パスを指定しないとダメで Examples のコピペだけだと cmap がみつからなくて 文字が表示されないこともあります
cmap がどうこうというエラーがでてたらパスを確認してみてください


とりあえず指定のページを画像化するコードはこうなりました
PDFJS.workerSrc = '/js/lib/pdf.js/build/pdf.worker.js';
PDFJS.cMapUrl = '/js/lib/pdf.js/web/cmaps/';
PDFJS.cMapPacked = true;

const toPNGURL = async ({pdf_path, pdf_data, page = 1}) => {
    const pdf_source = pdf_path || {data: pdf_data}
    const pdf = await PDFJS.getDocument(pdf_source)
    const pdf_page = await pdf.getPage(page)
    const viewport = pdf_page.getViewport(1)
    const canvas = Object.assign(document.createElement("canvas"), {
        width: viewport.width,
        height: viewport.height
    })
    await pdf_page.render({
        canvasContext: canvas.getContext("2d"),
        viewport,
    })
    return canvas.toDataURL()
}

toPNGURL({pdf_path: "/path/to/sample.pdf"}).then(e => console.log(e))

cMapPacked は bcmap ファイルなら true になるようです


画像化する方法は canvas の toDataURL を使ってます
PDFJS にサムネイルみたいな画像用の機能があるのかと思って viewer.js を見ていたのですが ここのサムネイルも自分で toDataURL() していました

一応 pdf.js/pdf.worker.js の中には jpeg や png ってキーワードがあって 画像変換もできそうなのですが viewer では使ってなさそうですし 使い方もよくわからないので とりあえず canvas から直接画像にしてます


画像のサイズは scale (倍率) を getViewport に指定して canvas のサイズをそれに合わせて変えます
今回は等倍サイズでよかったので 1 になってます

横 480px にしたい みたいなピクセル指定するなら一度 scale を 1 で viewport を受け取ってその横サイズから何倍にすれば 480px になるか計算することになります


今回は Example と viewer の一部だけを参考に画像ファイル化しただけですが ファイルサイズからすると もっと色々機能はありそう

将来的に編集とか他のドキュメントファイル(XPS とか)のサポートもあったらいいなー とうっすら期待してみる