注釈
ビューアに注釈サポートを追加
Doconut の注釈は二方向で機能します。ユーザーはブラウザウィジェット上で描画し、サーバーがページ単位で永続化するか、またはコードでプログラム的に作成し、開いているセッションにロードします。いずれの場合もページ上に描画され、PDF/PNG エクスポートに焼き込むことができます。
注釈サポートは Annotation ライセンス機能で制御されます(アクティブな Temporary ライセンスがある場合に自動的に付与されます)。
注釈 UI を有効化
注釈は Viewer のモジュールであり、単体のツールバーではありません。完全なページには Viewer リソース、Viewer ツールバー、Viewer のマウント、そして初期化された objViewer が含まれる必要があります。その後、Annotation Ribbon がマウントされ、同じインスタンスに添付されます。
注釈バンドルを Viewer バンドルと同時に出力します — これらはライセンスで制御されるため、機能が利用可能なときだけタグが表示されます:
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
IncludeViewerCss = true,
IncludeAnnotationCss = true // jquery-ui.min.css + annotationBar.css
}))
@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
IncludeJQuery = true,
IncludeViewerScripts = true,
IncludeAnnotationScripts = true, // jquery-ui, raphael.js, annotation.js
IncludeAnnotationBar = true // the embedded annotation ribbon
}))マークアップ内で完全な Viewer 構成を可視化したままにします:
<nav id="toolbar" aria-label="Document viewer controls">
<!-- ビューアのコントロール、Annotation を開くボタンを含む -->
</nav>
<div id="annBarMount"></div>
<div id="divDocViewer"><div id="div_ctlDoc"></div></div>annBarMount 内に Ribbon の DOM を生成するのは Annotation バンドルです;ボタンやダイアログのマークアップをコピーする必要はありません。まず docViewer を初期化し、サーバーが注釈がライセンスされていることを確認したときにのみ Ribbon を作成します:
<script>
let annBar = null;
let currentToken = '';
const objViewer = $('#div_ctlDoc').docViewer({
BasePath: 'doconut',
ResPath: 'doconut-res/images',
onAnnLoaded: () => annBar?.handleAnnLoaded(),
onAnnSaved: () => annBar?.handleAnnSaved(),
onAnnSaveError: () => annBar?.handleAnnSaveError(),
onAnnClosed: () => annBar?.handleAnnClosed(),
onError: (message) => console.error('Viewer error:', message)
});
@if (Viewer.IsAnnotationEnabled)
{
<text>
annBar = $('#annBarMount').doconutAnnotationBar({
docId: 'ctlDoc',
getRequestParams: () => ({ token: currentToken }),
onStatus: (message) => console.log(message),
onToast: (message, type) => console.log(type, message),
onLayout: () => requestAnimationFrame(() => objViewer.Refit())
});
annBar.attach(objViewer);
</text>
}
</script>Ribbon からの保存はミドルウェア (AnnSave) を通じてデータを投稿し、ページ単位でドキュメントセッションに保存します。読み込み (AnnLoad) は注釈付きページがレンダリングされると自動的に行われます。4 つの onAnn* コールバックが Ribbon と Viewer のライフサイクルを同期させます。
任意のホスト所有の Viewer ツールバーから開閉できます:
annBar.open();
annBar.close();公開されている Ribbon API は次のとおりです:
| メソッド | 目的 |
|---|---|
attach(objViewer) | 初期化されたビューアに Ribbon を接続します;一度だけ必要です |
open() / close() | 注釈編集モードに入るまたは退出する |
reset() | Ribbon を閉じた編集なしの状態に戻します |
isOpen() / annotating() | Ribbon の状態 / ビューアの注釈編集状態を取得します |
reopenEditable() | 現在のページの注釈を編集可能オブジェクトとして再読み込みします |
updateActionState() | ホストの変更後に保存/削除コントロールの利用可能状態を更新します |
headerSlot() | ホスト所有のコントロール用オプションヘッダー拡張スロットを取得します |
onStatus、onToast、onLayout、onEditStart、onEditEnd はオプションのホストコールバックです。endpoints オブジェクトはさらに exportPdf、exportPng、imageUpload、imageList を提供できます;設定されたエンドポイントがないコントロールは非表示のままです。統合された Viewer、Search、Annotation の起動シーケンスについては、クイックスタート を参照してください。
注釈バンドルはブラウザの作成ツールを追加しますが、データはトークンで識別されるサーバー側のドキュメントセッションに属したままです。ソースを再度開くと新しいセッションが作成されます;セッションの存続期間を超えて注釈を保持する必要がある場合は、XML またはエンコードされた注釈エンベロープをアプリケーションに永続化してください。
C# で注釈を作成する
オープンセッションにバインドされたマネージャーを取得し、注釈を追加してロードします(型には using Doconut.Annotations;、Rectangle/Color には using System.Drawing; を使用します)。
app.MapPost("/api/annotations/load-sample", (string token, Viewer viewer) =>
{
// 開いているセッションのページ寸法にバインドされる
var manager = viewer.GetAnnotationManager(token);
var pageCount = viewer.GetPageCount(token);
// ページごとに1つのスタンプ
for (int page = 1; page <= pageCount; page++)
{
manager.Add(new StampAnnotation(page, new Rectangle(30, 20, 240, 90),
$"PAGE {page}", 28, 4, Color.Maroon)
{
Opacity = 60,
Rotate = -8
});
}
manager.Add(new NoteAnnotation(1, new Rectangle(420, 150, 220, 120),
"Loaded from C# code.", Color.FromArgb(255, 255, 255, 170), 14));
// セッションにロードする — ウィジェットは AnnLoad 経由でそれらを取得し、
// renderer はそれらを画像/PDF エクスポートに焼き付けます。
viewer.LoadAnnotationData(token, manager);
return Results.Ok();
});注釈タイプ
Doconut.Annotations にすべてのタイプがあり、BaseAnnotation(ページ番号 + バウンディング Rectangle)を継承します。
| タイプ | 備考 |
|---|---|
StampAnnotation | フォントサイズ、枠線、色を持つテキストスタンプ;Opacity、Rotate をサポート |
NoteAnnotation | テキスト、背景色、フォントサイズ、TitleColor を持つ付箋ノート |
RectangleAnnotation | 枠線と塗りつぶし色、Title/ShowTitle |
CircleAnnotation | 枠線と塗りつぶし、ShowBorder |
EllipseAnnotation | 枠線と塗りつぶし、ShowBorder |
TriangleAnnotation | 枠線色、BackColor、ShowBorder |
LineAnnotation | 幅と色を持つ直線 |
ArrowAnnotation | 矢じり付きの線;設定可能な Direction(型 ArrowDirection、コンパス方向、デフォルトは E) |
FreehandAnnotation | エンコードされた FreehandData ポイントからのフリーストローク |
ImageAnnotation | URL からの画像。相対 URL は注釈が追加される際にリクエストホストに対して解決されます(画像取得は焼き込み時にのみ行われます)—サーバーからアクセス可能である必要があります(例: UseStaticFiles で提供される wwwroot 配下のファイル)。 |
AnnotationManager API
| メンバー | 目的 |
|---|---|
Add(BaseAnnotation) | 注釈をキューに入れる |
GetAnnotations() / GetAnnotations(int page) | マネージャーが保持しているものを確認する |
ClearAnnotations() / ClearAnnotations(int page) | すべて / ページ単位で削除する |
GetAnnotationData() / GetAnnotationData(int page) | エンコードされた注釈データ文字列 — Base64 のワイヤーエンベロープ(ウィジェットが消費するもの) |
GetAnnotationXml() | XML 形式 |
Viewer はセッションに対するロード/読み取り操作を鏡像します:LoadAnnotationData(token, manager) または LoadAnnotationData(token, encodedData)(GetAnnotationData() からの Base64 ワイヤーエンベロープ)、LoadAnnotationXML(token, xml)、GetAnnotationXML(token)。
注釈が焼き込まれた状態でエクスポート
// 注釈がレンダリングされたすべてのページの PDF
app.MapGet("/api/annotations/export-pdf", async (string token, Viewer viewer) =>
{
byte[] pdf = await viewer.ExportAnnotationsToPdfAsync(token, zoom: 100);
return Results.File(pdf, "application/pdf", "export.pdf");
});
// またはページごとの PNG の ZIP
app.MapGet("/api/annotations/export-png-zip", async (string token, Viewer viewer) =>
{
byte[] zip = await viewer.ExportAnnotationsToPngZipAsync(token, zoom: 100);
return Results.File(zip, "application/zip", "annotations-png.zip");
});エクスポートは画面上のレンダリングと同じバーナーを使用するため、ユーザーが見るものがファイルに含まれます。
永続化ワークフロー
- ドキュメントを開き、そのトークンを取得します。
- 以前に保存された XML またはエンコードされたデータをそのトークンにロードします。
- ウィジェットにセッション注釈を読み取り、編集させます。
- アプリケーションが永続化を決定したときに
GetAnnotationXML(token)で XML を取得します。 - フラット化された納品物が必要な場合は PDF/PNG をエクスポートします。
- ドキュメントセッションを閉じます。
不透明なビューアートークンを永続的な注釈識別子として使用しないでください。永続化された注釈データは、独自のドキュメントおよびバージョン識別子と関連付けてください。
セキュリティとレンダリングに関する注意点
- アノテーションリクエストは、ページリクエストと同じセッション/トークンのセキュリティを使用します。
- 相対的な
ImageAnnotationURL はリクエストホストから解決され、焼き込み時にサーバーから到達可能である必要があります。 - サーバー側リクエスト偽装を防ぐため、ユーザー提供の画像URLを検証および制御してください。
- エクスポートは、画面上のページレンダリングと同じライセンス/カスタム透かしの決定を適用します。
- 大きなフリーハンドペイロードや高解像度エクスポートはメモリ使用量を増加させます。実際的なドキュメントとズーム値でテストしてください。
トラブルシューティング
| 症状 | 確認項目 |
|---|---|
| アノテーションリボンが欠落している | Annotation 機能と4つのアノテーション CSS/スクリプト フラグ |
| 保存コールバックがエラーを報告する | トークン/セッションの期限切れとミドルウェア BasePath |
| C# アノテーションが表示されない | ページ番号が1ベースで、データがアクティブなトークンにロードされている |
| 画像アノテーションが画面上には表示されるが、エクスポートに含まれない | サーバーが焼き込み中に画像URLに到達できる |
| 再度開いたドキュメントにアノテーションがない | ビューアセッションの外部に XML/データを永続化し、新しいトークンにロードする |
このページは役に立ちましたか?