You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
5.3 KiB

1 month ago
# Cursor プロジェクト説明(iText7 で PDF に「メモ用レイヤー」を 2 つ追加)
## 目的
既存の PDF に **OCG(Optional Content Group=レイヤー)を 2 つ** 追加し、後からそのレイヤーにメモ(テキスト/図形/注釈)を書き込めるようにします。
Acrobat の「レイヤー」パネルで表示・非表示を切り替えられる **「メモ1」「メモ2」** を作成します。
## ゴール/受け入れ基準
* 既存 PDF を入力に取り、出力 PDF のカタログに **OCProperties/OCGs** が作成されていること(2 つの OCG)。
* Acrobat / PDF-XChange 等で **レイヤー「メモ1」「メモ2」** が確認でき、ON/OFF 切り替えが可能。
* 追加サンプルとして、各レイヤーに 1 行テキストを描画(または四角形)できること。
* 既存ページのコンテンツは変更しない(上に重ねるだけ)。
## 技術ポイント(PDF 構造)
* iText7 では `PdfLayer`(= OCG)を生成し、`PdfCanvas.beginLayer(layer) ... endLayer()` の間で描画したコンテンツはそのレイヤーに属します。
* 既存 PDF を開いてレイヤーを「追加」するだけなら、iText が **Catalog/OCProperties** を自動で拡張してくれます。
* 初期表示状態(ON/OFF)は `layer.setOn(true/false)` で制御可能。
## 環境
* 言語:Java 17(推奨 11+)
* ビルド:Maven もしくは Gradle
* ライブラリ:iText7(kernel / layout)
* Maven:
```xml
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>8.0.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>8.0.2</version>
</dependency>
```
* Gradle:
```gradle
implementation "com.itextpdf:kernel:8.0.2"
implementation "com.itextpdf:layout:8.0.2"
```
## プロジェクト構成(推奨)
```
pdf-memo-layers/
├─ README.md
├─ build.gradle or pom.xml
├─ src/
│ └─ main/java/
│ └─ co/jp/techsor/pdf/
│ ├─ App.java // CLI エントリ
│ ├─ PdfMemoLayerService.java // レイヤー作成・描画の中核
│ ├─ LayerDrawingOptions.java // 文字/図形の描画オプション
│ └─ util/
│ └─ PdfUtils.java // 共通ユーティリティ
└─ samples/
├─ input.pdf
└─ output.pdf (生成物)
```
## 主要ユースケース
1. **レイヤーだけを追加**(後で編集者が注釈・図形を載せる)
2. **レイヤーにテキスト/図形を同時に配置**(例:右下に “Memo Layer”)
3. **初期状態の切替**(メモ1=ON、メモ2=OFF など)
## CLI 仕様(例)
```
java -jar pdf-memo-layers.jar \
--in samples/input.pdf \
--out samples/output.pdf \
--layer1 "メモ1" --layer2 "メモ2" \
--draw "text:1,100,700,メモ1のサンプル" \
--draw "rect:2,50,50,200,60" \
--l2-on=false
```
* `--draw` は複数指定可。形式:
* `text:<layerIndex(1|2)>,<x>,<y>,<content>`
* `rect:<layerIndex(1|2)>,<x>,<y>,<w>,<h>`
* `--l2-on=false` のように初期表示を切替。
## 実装概略(擬似コード)
```java
try (PdfDocument pdf =
new PdfDocument(new PdfReader(inPath), new PdfWriter(outPath))) {
// 1) レイヤー(OCG)作成
PdfLayer memo1 = new PdfLayer("メモ1", pdf);
memo1.setOn(true); // 初期表示 ON
PdfLayer memo2 = new PdfLayer("メモ2", pdf);
memo2.setOn(false); // 初期表示 OFF(例)
// 2) 必要に応じて描画(各ページの上に重ねる)
PdfPage page1 = pdf.getPage(1);
PdfCanvas canvas1 = new PdfCanvas(page1);
canvas1.beginLayer(memo1);
// テキスト描画(iText7 layout を使う場合は Canvas を併用)
try (Canvas c = new Canvas(canvas1, page1.getPageSize())) {
c.showTextAligned("メモ1のサンプル", 100, 700, TextAlignment.LEFT);
}
canvas1.endLayer();
PdfPage page2 = pdf.getPage(2);
PdfCanvas canvas2 = new PdfCanvas(page2);
canvas2.beginLayer(memo2);
canvas2.rectangle(50, 50, 200, 60);
canvas2.stroke();
canvas2.endLayer();
}
```
## テスト手順
1. `samples/input.pdf` を用意し、CLI で実行して `samples/output.pdf` を生成。
2. Acrobat で `output.pdf` を開き、**表示 → ナビゲーションパネル → レイヤー** を表示。
3. 「メモ1」「メモ2」の存在と ON/OFF の切り替えで描画が出入りすることを確認。
## エッジケースと対策
* **暗号化 PDF**:所有者パスワードが必要。`ReaderProperties`/`WriterProperties` で設定。
* **透明度・ブレンド**:必要なら `PdfExtGState` を併用して半透明表現。
* **注釈に載せたい**:注釈は OCG 直付けできないため、描画をレイヤーに、注釈は通常オブジェクトとして扱う(見た目同期が必要)。
* **長文テキスト**:`layout` の `Paragraph` を使用し、行送りとフォント設定を行う。
## ライセンス注意
iText 7 は AGPL もしくは商用ライセンスです。社内/顧客配布要件に合わせてライセンス選定を行ってください。