PDF内のアノテーションを管理できます。
PDFにはコメント、提案、マークアップのような図形やハイライトをアノテーション(注釈)として追加できます。
アノテーションはページとは別のレイヤに適用されます。そのため、アノテーションはページコンテンツの一部ではありません。
通常のページコンテンツとは異なり、多くのアノテーションタイプはPDFビューアでインタラクティブに動作します。
Toolbox Add-onは以下のタイプのアノテーションに対応しています。
HighlightPopupStickyNoteStrikeThroughUnderlineFreeTextEllipseInkLinePolygonPolyLineRectangleSquigglyInternalLinkWebLinkTextStampCustomStampFileAttachmentToolbox Add-onのAPIリファレンスはこちらです。(すべて英文)
C#のサンプルプロジェクトではPdftools SDK(Toolbox Add-on)ライブラリ(DLL)をNuGetから自動でダウンロードします。
CのサンプルプロジェクトにはPdftools SDK(Toolbox Add-on)ライブラリ(DLL)が含まれています。
License Agreement(利用許諾契約書)が含まれていますので必ず確認してください。
入力PDFの内容を出力PDFにコピーして、コピーされた出力PDFにアノテーションを追加します。
// 入力PDFファイルを開く
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
// 出力PDFを生成
using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
// ドキュメント全体のデータをコピー
CopyDocumentData(inDoc, outDoc);
// コピーオプションを定義
PageCopyOptions copyOptions = new PageCopyOptions();
// 最初のページをコピーして注釈を追加
Page outPage = CopyAndAddAnnotations(outDoc, inDoc.Pages[0], copyOptions);
// 出力ドキュメントのページリストにページを追加
outDoc.Pages.Add(outPage);
// 残りのページをコピーし、出力ドキュメントのページリストに追加
PageList inPages = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList outPages = PageList.Copy(outDoc, inPages, copyOptions);
outDoc.Pages.AddRange(outPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// ドキュメント全体のデータをコピー
// 出力色特性設定
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// メタデータ
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// ビュワー設定
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// プレーンな埋め込みファイル
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static Page CopyAndAddAnnotations(Document outDoc, Page inPage, PageCopyOptions copyOptions)
{
// ページを出力ドキュメントにコピー
Page outPage = Page.Copy(outDoc, inPage, copyOptions);
// RGB色空間作成
ColorSpace rgb = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);
// 注釈を配置するためのページサイズを取得
Size pageSize = outPage.Size;
// 注釈を追加するための出力ページの注釈リストを取得
AnnotationList annotations = outPage.Annotations;
// 付箋(sticky note)を作成し、出力ページの注釈に追加
Paint green = Paint.Create(outDoc, rgb, new double[] { 0, 1, 0 }, null);
Point stickyNoteTopLeft = new Point() { X = 10, Y = pageSize.Height - 10 };
StickyNote stickyNote = StickyNote.Create(outDoc, stickyNoteTopLeft, "Hello world!", green);
annotations.Add(stickyNote);
// 楕円を作成し、出力ページの注釈に追加
Paint blue = Paint.Create(outDoc, rgb, new double[] { 0, 0, 1 }, null);
Paint yellow = Paint.Create(outDoc, rgb, new double[] { 1, 1, 0 }, null);
Rectangle ellipseBox = new Rectangle() { Left = 10, Bottom = pageSize.Height - 60, Right = 70, Top = pageSize.Height - 20 };
EllipseAnnotation ellipse = EllipseAnnotation.Create(outDoc, ellipseBox, new Stroke(blue, 1.5), yellow);
annotations.Add(ellipse);
// フリーテキストを作成し、出力ページの注釈に追加
Paint yellowTransp = Paint.Create(outDoc, rgb, new double[] { 1, 1, 0 }, new Transparency(0.5));
Rectangle freeTextBox = new Rectangle() { Left = 10, Bottom = pageSize.Height - 170, Right = 120, Top = pageSize.Height - 70 };
FreeText freeText = FreeText.Create(outDoc, freeTextBox, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", yellowTransp);
annotations.Add(freeText);
// 既存のページコンテンツ要素にフィットするハイライトとウェブリンク
Highlight highlight = null;
WebLink webLink = null;
// 入力ページからコンテンツ要素を抽出
ContentExtractor extractor = new ContentExtractor(inPage.Content);
foreach (ContentElement element in extractor)
{
// 最初のテキスト要素を取得
if (highlight == null && element is TextElement textElement)
{
// このテキスト要素の矩形を取得
QuadrilateralList quadrilaterals = new QuadrilateralList();
foreach (TextFragment fragment in textElement.Text)
quadrilaterals.Add(fragment.Transform.TransformRectangle(fragment.BoundingBox));
// ハイライトを作成し、出力ページの注釈に追加
highlight = Highlight.CreateFromQuadrilaterals(outDoc, quadrilaterals, yellow);
annotations.Add(highlight);
}
// 最初の画像要素を取得
if (webLink == null && element is ImageElement)
{
// この画像の矩形を取得
QuadrilateralList quadrilaterals = new QuadrilateralList();
quadrilaterals.Add(element.Transform.TransformRectangle(element.BoundingBox));
// ウェブリンクを作成し、出力ページのリンクに追加
webLink = WebLink.CreateFromQuadrilaterals(outDoc, quadrilaterals, "https://www.pdf-tools.com");
Paint red = Paint.Create(outDoc, rgb, new double[] { 1, 0, 0 }, null);
webLink.BorderStyle = new Stroke(red, 1.5);
outPage.Links.Add(webLink);
}
// ハイライトとウェブリンクが作成された場合はループを終了
if (highlight != null && webLink != null)
break;
}
// 完成したページを戻す
return outPage;
}
def copy_document_data(in_doc: Document, out_doc: Document):
# ドキュメント全体のデータをコピー
# 出力色特性設定
if in_doc.output_intent is not None:
in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
# メタデータ
out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
# ビュワー設定
out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
# 関連ファイル(PDF/A-3およびPDF 2.0のみ)
outAssociatedFiles = out_doc.associated_files
for in_file_ref in in_doc.associated_files:
outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
# プレーンな埋め込みファイル
out_embedded_files = out_doc.plain_embedded_files
for in_file_ref in in_doc.plain_embedded_files:
out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
def copy_and_add_annotations(out_doc: Document, in_page: Page, copy_options: PageCopyOptions):
# ページを出力ドキュメントにコピー
out_page = Page.copy(out_doc, in_page, copy_options)
# RGB色空間作成
rgb = ColorSpace.create_process_color_space(out_doc, ProcessColorSpaceType.RGB)
# 注釈を配置するためのページサイズを取得
page_size = out_page.size
# 注釈を追加するための出力ページの注釈リストを取得
annotations = out_page.annotations
# 付箋(sticky note)を作成し、出力ページの注釈に追加
green = Paint.create(out_doc, rgb, [0.0, 1.0, 0.0], None)
sticky_note_top_left = Point(x=10.0, y=page_size.height - 10.0)
sticky_note = StickyNote.create(out_doc, sticky_note_top_left, "Hello world!", green)
annotations.append(sticky_note)
# 楕円を作成し、出力ページの注釈に追加
blue = Paint.create(out_doc, rgb, [0.0, 0.0, 1.0], None)
yellow = Paint.create(out_doc, rgb, [1.0, 1.0, 0.0], None)
ellipse_box = Rectangle(left=10.0, bottom=page_size.height - 60.0, right=70.0, top=page_size.height - 20.0)
ellipse = EllipseAnnotation.create(out_doc, ellipse_box, Stroke(blue, 1.5), yellow)
annotations.append(ellipse)
# フリーテキストを作成し、出力ページの注釈に追加
yellow_transp = Paint.create(out_doc, rgb, [1.0, 1.0, 0.0], Transparency(0.5))
free_text_box = Rectangle(left=10.0, bottom=page_size.height - 170.0, right=120.0, top=page_size.height - 70.0)
free_text = FreeText.create(out_doc, free_text_box, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", yellow_transp)
annotations.append(free_text)
# 既存のページコンテンツ要素にフィットするハイライトとウェブリンク
highlight = None
web_link = None
# 入力ページからコンテンツ要素を抽出
extractor = ContentExtractor(in_page.content)
for element in extractor:
# 最初のテキスト要素を取得
if highlight is None and isinstance(element, TextElement):
# このテキスト要素の矩形を取得
quadrilaterals = QuadrilateralList()
for fragment in element.text:
quadrilaterals.append(fragment.transform.transform_rectangle(fragment.bounding_box))
# ハイライトを作成し、出力ページの注釈に追加
highlight = Highlight.create_from_quadrilaterals(out_doc, quadrilaterals, yellow)
annotations.append(highlight)
# 最初の画像要素を取得
if web_link is None and isinstance(element, ImageElement):
# この画像の矩形を取得
quadrilaterals = QuadrilateralList()
quadrilaterals.append(element.transform.transform_rectangle(element.bounding_box))
# ウェブリンクを作成し、出力ページのリンクに追加
web_link = WebLink.create_from_quadrilaterals(out_doc, quadrilaterals, "https://www.pdf-tools.com")
red = Paint.create(out_doc, rgb, [1.0, 0.0, 0.0], None)
web_link.border_style = Stroke(red, 1.5)
out_page.links.append(web_link)
# ハイライトとウェブリンクが作成された場合はループを終了
if highlight is not None and web_link is not None:
break
return out_page
# 入力PDFファイルを開く
with io.FileIO(input_file_path, 'rb') as in_stream:
with Document.open(in_stream, None) as in_doc:
# 出力PDFを生成
with io.FileIO(output_file_path, 'wb+') as output_stream:
with Document.create(output_stream, in_doc.conformance, None) as out_doc:
# ドキュメント全体のデータをコピー
copy_document_data(in_doc, out_doc)
# コピーオプションを定義
copy_options = PageCopyOptions()
# 最初のページをコピーして注釈を追加
out_page = copy_and_add_annotations(out_doc, in_doc.pages[0], copy_options)
# 出力ドキュメントのページリストにページを追加
out_doc.pages.append(out_page)
# 残りのページをコピーし、出力ドキュメントのページリストに追加
in_pages = in_doc.pages[1:]
out_pages = PageList.copy(out_doc, in_pages, copy_options)
out_doc.pages.extend(out_pages)
他の機能サンプルを参照してください。
質問のページからお送りいただくようお願いします。
または、メールでsupport@trustss.co.jpあてにお送りください。
ご購入前の技術的質問も無償で対応します。サポート受付ページからお願いします。