夜間の作業や長時間の論文読み、電子書籍リーダーでの閲覧において、「ダークモード」は現代のデジタル生活に欠かせない機能となりました。
しかし、ある日私は決定的な不満に直面しました。「PDFをダークモードで『表示』できるビューアアプリは世の中に山ほどあるのに、PDFそのものをダークモードに『変換して保存』できるツールがどこにも存在しない」ということです。
ビューアアプリが画面上で色を反転させていても、そのPDFを他の人へ共有したり、電子ペーパー端末やKindleに転送したり、標準の印刷ダイアログに送ると、元の眩しい「真っ白なPDF」に戻ってしまいます。
「なら自分で作ろう」と意気込んで始めたのがDarkModePDFの開発でした。しかし、そこにはPDFの仕様が立ちはだかる、想像を絶する変換ロジックの苦難が待っていました。
1. 「ビューアの反転」と「ファイルの恒久変換」の決定的な違い
| 機能 | 一般的なPDFビューア | DarkModePDF (本アプリ) |
|---|---|---|
| 仕組み | 画面描画(GPU)にネガ反転シェーダーをかけるだけ | PDFの内部バイナリ・命令ストリームを書き換えて保存 |
| 他端末・他アプリ共有 | ×(開く側のアプリで再設定が必要) | ◎(どの端末・どのアプリで開いても最初から黒背景) |
| 電子ペーパー / Kindle | ×(専用ビューアが動かない端末では白に戻る) | ◎(ファイルそのものがダークモードなので完璧に表示) |
2. 安易な「画像化(ラスタライズ)方式」が犯す致命傷
最も手っ取り早く変換PDFを作る方法は、「各ページを画像(PNG)としてレンダリングし、Canvasで色反転して新しいPDFに貼り直す」ことです。
しかしこの方法には、実用に耐えない致命的な欠陥が3つあります:
- 文字のベクター情報が消滅する: 拡大すると文字がギザギザに潰れ、鮮明さが失われます。
- テキスト選択・検索・コピペが全滅する: 単なる画像になってしまうため、重要なキーワード検索や翻訳コピペが一切できません。
- ファイルサイズが10倍以上に激増する: 1MBだった論文PDFが数十MBに膨れ上がり、端末ストレージを圧迫します。
したがって、「文字や線のベクター品質・テキスト情報を100%保持したまま、色情報だけを内部ストリームレベルで反転させる」という困難な道を選ぶしかありませんでした。
3. 開発で直面した3大ハードルと変換ロジックの工夫
① PDFには「背景」という概念が存在しない
PDFの仕様書を深く読み進めて最初に驚いたのは、大半のPDFには「白い背景」というオブジェクト自体が存在しないという事実です。
PDFは「白い物理用紙にインクを乗せる」という印刷機の発想で作られているため、何も描かれていない部分は単なる「透明(紙の白が透けて見えているだけ)」なのです。
ページのコンテンツストリームの先頭に、用紙サイズにぴったり合わせた黒い塗りつぶし矩形コマンド(q 0 0 0 rg ... re f Q)を強制的に割り込ませるパッチロジックを開発しました。
② 写真や図表がネガフィルム化する「ホラー画像問題」
ページ内の色命令を単純に全て反転させると、論文中のグラフや挿絵、筆者の顔写真までもがネガポジ反転され、まるでホラー映画のような不気味な青白い顔写真になってしまいます。
そこで開発したのが「スマートモード」です:
- PDF内の描画オペレータ(
rg/RG: RGB、g/G: グレースケール、k/K: CMYK)を解析し、文字・図形・罫線の色のみを反転。 - 埋め込み画像オブジェクト(XObject
/Subtype /Image)を検出し、写真やカラー図表はそのまま無傷で保護。
// 描画オペレータを直接書き換えるコアロジックの抜粋
// RGB色指定 (例: "0.1 0.1 0.1 rg") の明度を反転
modified = text.replace(/(\d+(?:\.\d+)?)([\s\0]+)(\d+(?:\.\d+)?)([\s\0]+)(\d+(?:\.\d+)?)([\s\0]+)(rg|RG)/g,
(match, r, s1, g, s2, b, s3, op) => {
return `${invert(parseFloat(r))}${s1}${invert(parseFloat(g))}${s2}${invert(parseFloat(b))}${s3}${op}`;
}
);
③ スマホ(React Native / JavaScript)のメモリ制限(OOM)
何百ページもある分厚いPDFや高解像度ファイルの場合、全ページを一度にメモリ上に展開するとスマートフォンのOSから容赦なくメモリ不足(Out Of Memory)でアプリが強制終了させられます。
これを防ぐため、ファイルサイズの事前バリデーション、1ページずつの逐次ストリーム処理、ガベージコレクションを促すバッファ解放など、徹底的なメモリ軽量化を積み重ねました。
4. まとめとWeb/PWA版への展開
「ビューアで間に合わせる」のではなく「ファイル自体を変換する」というアプローチをとったことで、Kindle、各種タブレット、Webブラウザなど、どんな環境に持っていっても美しく目に優しい読書体験を提供できるようになりました。
現在、Androidアプリ版(Google Play)に加え、インストール不要でPCやMacのブラウザから使えるDarkModePDF on Web/PWAも公開しています。夜間のPDF閲覧で目が疲れている方は、ぜひ試してみてください。
While there are countless PDF viewers that offer dark mode displays, there was no tool that could permanently convert and save the PDF itself into dark mode.
In this article, we share the technical story behind DarkModePDF: preserving vector clarity, bypassing the "missing background" quirk of PDF specs, and preventing embedded images from turning into inverted horror pictures.