PDF文書のContent(記載項目)を削除または追加します。
Toolbox add-onは以下のContent(記載項目)タイプを追加または削除します。
TextImageImage MaskPathToolbox Add-onのAPIリファレンスはこちらです。(すべて英文)
C#のサンプルプロジェクトではPdftools SDK(Toolbox Add-on)ライブラリ(DLL)をNuGetから自動でダウンロードします。
CのサンプルプロジェクトにはPdftools SDK(Toolbox Add-on)ライブラリ(DLL)が含まれています。
License Agreement(利用許諾契約書)が含まれていますので必ず確認してください。
PDFドキュメントの先頭ページの指定された位置にテキストを追加します。
// 入力PDFをオープン
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
szInPath, szErrorBuff, Ptx_GetLastError());
// 出力PDFを作成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
szOutPath, szErrorBuff, Ptx_GetLastError());
// 出力PDFに埋め込みフォントを作成
pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T("Italic"), TRUE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// ドキュメント全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// コピーオプションを設定
pCopyOptions = PtxPdf_PageCopyOptions_New();
// 入力PDFと出力PDFのページリストを取得
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
_T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 先頭ページをコピー
pInPage = PtxPdf_PageList_Get(pInPageList, 0);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get the first page. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// コピーしたページにテキストを追加
if (addText(pOutDoc, pOutPage, szTextString, pFont, 15) != 0)
goto cleanup;
// 出力PDFにページを追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
_T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 入力から残りのページを取得
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
_T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 取得した(残りの)ページを出力にコピー
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
_T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// コピーしたページを出力ドキュメントに追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
_T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// ビュワー設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addText(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szTextString, TPtxPdfContent_Font* pFont,
double dFontSize)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdfContent_Text* pText = NULL;
TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
TPtxGeomReal_Size size;
TPtxGeomReal_Point position;
double dFontAscent;
pContent = PtxPdf_Page_GetContent(pOutPage);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pContent, _T("Failed to get content of output file. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// コンテンツジェネレータを作成
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// テキストオブジェクトを作成
pText = PtxPdfContent_Text_Create(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create text object. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// テキストジェネレータを作成
pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, dFontSize, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 出力ページサイズを取得
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pOutPage, &size),
_T("Failed to read page size. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dFontAscent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// 位置を計算
position.dX = dBorder;
position.dY = size.dHeight - dBorder - dFontSize * dFontAscent;
// 計算された位置に移動
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position),
_T("Failed to move to position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// 指定されたテキスト文字列を追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szTextString),
_T("Failed to add text string. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// テキストジェネレータを閉じる
PtxPdfContent_TextGenerator_Close(pTextGenerator);
pTextGenerator = NULL;
// 配置されたテキストを描画
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText),
_T("Failed to paint the positioned text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
cleanup:
if (pTextGenerator != NULL)
PtxPdfContent_TextGenerator_Close(pTextGenerator);
if (pText != NULL)
Ptx_Release(pText);
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
// 入力PDFを開く
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// 出力ファイルを作成
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// ドキュメント全体のデータをコピー
CopyDocumentData(inDoc, outDoc);
// フォントを作成
font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
// ページのコピーオプションを定義
PageCopyOptions copyOptions = new PageCopyOptions();
// 先頭のページをコピーし、そこにテキストを追加して出力ドキュメントに追加
Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
AddText(outDoc, outPage, textString);
outDoc.Pages.Add(outPage);
// 残りのページをコピーして出力ドキュメントに追加
PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
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 void AddText(Document outputDoc, Page outPage, string textString)
{
// コンテンツジェネレータとテキストオブジェクトを作成
using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
Text text = Text.Create(outputDoc);
// テキストジェネレータを作成
using (TextGenerator textGenerator = new TextGenerator(text, font, fontSize, null))
{
// 位置を計算
Point position = new Point
{
X = border,
Y = outPage.Size.Height - border - fontSize * font.Ascent
};
// 計算された位置に移動
textGenerator.MoveTo(position);
// 指定されたテキスト文字列を追加
textGenerator.ShowLine(textString);
}
// 配置されたテキストを描画
gen.PaintText(text);
}
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 add_text(output_doc: Document, output_page: Page, text_string: str):
# コンテンツジェネレータとテキストオブジェクトを作成
with ContentGenerator(output_page.content, False) as gen:
text = Text.create(output_doc)
# テキストジェネレータを作成
with TextGenerator(text, font, font_size, None) as textGenerator:
# 位置を計算
position = Point(border, output_page.size.height - border - font_size * font.ascent)
# 位置に移動
textGenerator.move_to(position)
# 指定されたテキスト文字列を追加
textGenerator.show_line(text_string)
# 配置されたテキストを描画
gen.paint_text(text)
# グローバル変数を定義
border = 40.0
font_size = 15.0
# 入力PDFを開く
with io.FileIO(input_file_path, 'rb') as in_stream:
with Document.open(in_stream, None) as input_document:
# 出力ファイルを作成
with io.FileIO(output_file_path, 'wb+') as output_stream:
with Document.create(output_stream, input_document.conformance, None) as output_document:
# ドキュメント全体のデータをコピー
copy_document_data(input_document, output_document)
# フォントを作成
font = Font.create_from_system(output_document, "Arial", "Italic", True)
# ページのコピーオプションを定義
copy_options = PageCopyOptions()
# 先頭のページをコピーし、そこにテキストを追加して出力ドキュメントに追加
out_page = Page.copy(output_document, input_document.pages[0], copy_options)
add_text(output_document, out_page, text_string)
output_document.pages.append(out_page)
# 残りのページをコピーして出力ドキュメントに追加
inPageRange = input_document.pages[1:]
copied_pages = PageList.copy(output_document, inPageRange, copy_options)
output_document.pages.extend(copied_pages)
入力PDFの文字列を出力PDFにコピーする際に、先頭2文字を削除してから出力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);
// 各ページを処理
foreach (var inPage in inDoc.Pages)
{
// 空の出力ページを作成
Page outPage = Page.Create(outDoc, inPage.Size);
// 入力から出力にページコンテンツをコピーし、グリフを削除
CopyContentAndRemoveGlyphs(inPage.Content, outPage.Content, outDoc);
// 新しいページを出力ドキュメントのページリストに追加
outDoc.Pages.Add(outPage);
}
}
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 void CopyContentAndRemoveGlyphs(Content inContent, Content outContent, Document outDoc)
{
// コンテンツ抽出ツールとコンテンツジェネレータを使用してコンテンツをコピー
ContentExtractor extractor = new ContentExtractor(inContent);
using ContentGenerator generator = new ContentGenerator(outContent, false);
// すべてのコンテンツ要素を反復処理
foreach (ContentElement inElement in extractor)
{
ContentElement outElement;
// グループ要素の特別な処理
if (inElement is GroupElement inGroupElement)
{
// 空の出力グループ要素を作成
GroupElement outGroupElement = GroupElement.CopyWithoutContent(outDoc, inGroupElement);
outElement = outGroupElement;
// グループ要素のコンテンツに対してCopyContentAndRemoveGlyphs()を再帰的にコール
CopyContentAndRemoveGlyphs(inGroupElement.Group.Content, outGroupElement.Group.Content, outDoc);
}
else
{
// コンテンツ要素を出力ファイルにコピー
outElement = ContentElement.Copy(outDoc, inElement);
if (outElement is TextElement outTextElement)
{
// テキスト要素の特別な処理
Text text = outTextElement.Text;
// 各テキストフラグメントから最初の2つのグリフを削除
foreach (var fragment in text)
{
// フラグメントに2つ以上のグリフがあることを確認
if (fragment.Count > 2)
{
// RemoveAtを2回コール
fragment.RemoveAt(0);
fragment.RemoveAt(0);
}
}
}
}
// 完成した出力要素をコンテンツジェネレーターに追加
generator.AppendContentElement(outElement);
}
}
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_content_and_remove_glyphs(in_content: Content, out_content: Content, out_doc: Document):
"""Process content to remove the first two glyphs from text fragments."""
# コンテンツ抽出ツールとコンテンツジェネレータを使用してコンテンツをコピー
extractor = ContentExtractor(in_content)
with ContentGenerator(out_content, False) as generator:
# すべてのコンテンツ要素を反復処理
for in_element in extractor:
# グループ要素の特別な処理
if isinstance(in_element, GroupElement):
# 空の出力グループ要素を作成
out_group_element = GroupElement.copy_without_content(out_doc, in_element)
out_element = out_group_element
copy_content_and_remove_glyphs(in_element.group.content, out_group_element.group.content, out_doc)
else:
# コンテンツ要素を出力ファイルにコピー
out_element = ContentElement.copy(out_doc, in_element)
if isinstance(out_element, TextElement):
# テキスト要素の特別な処理
text = out_element.text
# 各テキストフラグメントから最初の2つのグリフを削除
for fragment in text:
# フラグメントに2つ以上のグリフがあることを確認
if len(fragment) > 2:
# RemoveAtを2回コール
fragment.remove(0)
fragment.remove(0)
# 完成した出力要素をコンテンツジェネレーターに追加
generator.append_content_element(out_element)
# 入力PDFを開き、出力ファイルを生成
with io.FileIO(input_file_path, "rb") as in_stream:
with Document.open(in_stream, None) as in_doc:
# 出力ファイルを生成
with io.FileIO(output_file_path, "wb+") as out_stream:
with Document.create(out_stream, in_doc.conformance, None) as out_doc:
# ドキュメント全体のデータをコピー
copy_document_data(in_doc, out_doc)
# 各ページを処理
for in_page in in_doc.pages:
# 空の出力ページを作成
out_page = Page.create(out_doc, in_page.size)
# 入力から出力にページコンテンツをコピーし、グリフを削除
copy_content_and_remove_glyphs(in_page.content, out_page.content, out_doc)
# 新しいページを出力ドキュメントのページリストに追加
out_doc.pages.append(out_page)
サイズ指定された画像をページの指定場所に配置します。
// 入力PDFを開く
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot cannot be opened. %s (ErrorCode: 0x%08x).\n"),
szInPath, szErrorBuff, Ptx_GetLastError());
// 出力PDFを作成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
szOutPath, szErrorBuff, Ptx_GetLastError());
// ドキュメント全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// コピーオプションを設定
pCopyOptions = PtxPdf_PageCopyOptions_New();
// 入力ページと出力ページのリストを取得
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
_T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 先頭ページから選択されたページより前までをコピー
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 0, iPageNumber - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange, _T("Failed to copy page range. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
_T("Failed to add page range. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
Ptx_Release(pInPageRange);
pInPageRange = NULL;
Ptx_Release(pOutPageRange);
pOutPageRange = NULL;
// 選択したページをコピーして画像を追加
pInPage = PtxPdf_PageList_Get(pInPageList, iPageNumber - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
if (addImage(pOutDoc, pOutPage, szImagePath, 150.0, 150.0) != 0)
goto cleanup;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
_T("Failed to add page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// 残りのページをコピー
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
_T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
_T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
_T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// ビュワー設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addImage(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szImagePath, double x, double y)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxSys_StreamDescriptor imageDescriptor;
FILE* pImageStream = NULL;
TPtxPdfContent_Image* pImage = NULL;
pContent = PtxPdf_Page_GetContent(pOutPage);
// コンテンツジェネレータを作成
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
// 入力パスからの画像読み込み
pImageStream = _tfopen(szImagePath, _T("rb"));
PtxSysCreateFILEStreamDescriptor(&imageDescriptor, pImageStream, 0);
// 画像オブジェクトを作成
pImage = PtxPdfContent_Image_Create(pOutDoc, &imageDescriptor);
double dResolution = 150.0;
TPtxGeomInt_Size size;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Image_GetSize(pImage, &size),
_T("Failed to get image size. %s(ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// データ行列の矩形を計算
TPtxGeomReal_Rectangle rect;
rect.dLeft = x;
rect.dBottom = y;
rect.dRight = x + (double)size.iWidth * 72.0 / dResolution;
rect.dTop = y + (double)size.iHeight * 72.0 / dResolution;
// 指定されたに矩形画像を描画
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintImage(pGenerator, pImage, &rect),
_T("Failed to paint image. %s(ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
cleanup:
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
// 入力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();
// 先頭ページから選択したページの前までのページをコピーし、出力ドキュメントに追加
PageList inPageRange = inDoc.Pages.GetRange(0, pageNumber - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
// 選択したページをコピーし、画像を追加して出力ドキュメントに追加
Page outPage = Page.Copy(outDoc, inDoc.Pages[pageNumber - 1], copyOptions);
AddImage(outDoc, outPage, imagePath, 150, 150);
outDoc.Pages.Add(outPage);
// 残りのページをコピーして出力ドキュメントに追加
inPageRange = inDoc.Pages.GetRange(pageNumber, inDoc.Pages.Count - pageNumber);
copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
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 void AddImage(Document document, Page page, string imagePath, double x, double y)
{
// コンテンツジェネレータを作成
using ContentGenerator generator = new ContentGenerator(page.Content, false);
// 入力パスからの画像読み込み
using Stream inImage = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
// 画像オブジェクトを作成
Image image = Image.Create(document, inImage);
double resolution = 150;
// 画像の矩形を計算
PdfTools.Toolbox.Geometry.Integer.Size size = image.Size;
Rectangle rect = new Rectangle
{
Left = x,
Bottom = y,
Right = x + size.Width * 72 / resolution,
Top = y + size.Height * 72 / resolution
};
// 指定された矩形に画像を描画
generator.PaintImage(image, rect);
}
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およびPDF2.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 add_image(document: Document, page: Page, image_path: str, x: float, y: float):
# コンテンツジェネレータを作成
with ContentGenerator(page.content, False) as generator:
# 入力パスからの画像読み込み
with io.FileIO(image_path, 'rb') as in_image_stream:
# 画像オブジェクトを作成
image = Image.create(document, in_image_stream)
resolution = 150
# 画像の矩形を計算
size = image.size
rect = Rectangle(
left=x,
bottom=y,
right=x + size.width * 72 / resolution,
top=y + size.height * 72 / resolution
)
# 指定された矩形に画像を描画
generator.paint_image(image, rect)
# 入力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()
# 先頭ページから選択したページの前までのページをコピーし、出力ドキュメントに追加
if page_number > 1:
in_page_range = in_doc.pages[:page_number - 1]
copied_pages = PageList.copy(out_doc, in_page_range, copy_options)
out_doc.pages.extend(copied_pages)
# 選択したページをコピーし、画像を追加して出力ドキュメントに追加
out_page = Page.copy(out_doc, in_doc.pages[page_number - 1], copy_options)
add_image(out_doc, out_page, image_path, 150, 150)
out_doc.pages.append(out_page)
# 残りのページをコピーして出力ドキュメントに追加
in_page_range = in_doc.pages[page_number:]
copied_pages = PageList.copy(out_doc, in_page_range, copy_options)
out_doc.pages.extend(copied_pages)
ページ上の指定した位置に長方形のマスク画像を配置します。
マスク画像は、画像をピクセル単位で塗りつぶしたりマスクしたりするステンシルマスクです。
// 入力PDFを開く
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(_T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// 出力PDFを作成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(_T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// ドキュメント全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// デバイス色空間を取得
TPtxPdfContent_ColorSpace* pColorSpace =
PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pColorSpace, _T("Failed to get the device color space. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// RGBカラー値を選択
double color[] = {1.0, 0.0, 0.0};
size_t nColor = sizeof(color) / sizeof(double);
// 描画オブジェクトを作成
pPaint = PtxPdfContent_Paint_Create(pOutDoc, pColorSpace, color, nColor, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pPaint, _T("Failed to create a transparent paint. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// コピーオプションを設定
pCopyOptions = PtxPdf_PageCopyOptions_New();
// 入力ページと出力ページのリストを取得
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
_T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 最初のページをコピーして画像マスクを追加
pInPage = PtxPdf_PageList_Get(pInPageList, 0);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
if (addImageMask(pOutDoc, pOutPage, szImageMaskPath, 250, 150) != 0)
goto cleanup;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
_T("Failed to add page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// 残りのページをコピー
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
_T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
_T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
_T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// 表示設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル (PDF/A-3およびPDF2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addImageMask(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szImageMaskPath, double x, double y)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
FILE* pImageStream = NULL;
TPtxSys_StreamDescriptor imageDescriptor;
TPtxPdfContent_ImageMask* pImageMask = NULL;
pContent = PtxPdf_Page_GetContent(pOutPage);
// コンテンツジェネレータを作成
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 入力パスからの画像読み込み
pImageStream = _tfopen(szImageMaskPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pImageStream, _T("Failed to open image mask file \"%s\".\n"), szImageMaskPath);
PtxSysCreateFILEStreamDescriptor(&imageDescriptor, pImageStream, 0);
// 画像マスクオブジェクトを作成
pImageMask = PtxPdfContent_ImageMask_Create(pOutDoc, &imageDescriptor);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pImageMask, _T("Failed to create image mask obejct. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
double dResolution = 150.0;
TPtxGeomInt_Size size;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ImageMask_GetSize(pImageMask, &size),
_T("Failed to get image mask size. %s(ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// データ行列の矩形を計算
TPtxGeomReal_Rectangle rect;
rect.dLeft = x;
rect.dBottom = y;
rect.dRight = x + (double)size.iWidth * 72.0 / dResolution;
rect.dTop = y + (double)size.iHeight * 72.0 / dResolution;
// 指定された矩形に画像マスクを描画
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
PtxPdfContent_ContentGenerator_PaintImageMask(pGenerator, pImageMask, &rect, pPaint),
_T("Failed to paint image mask. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
// 入力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);
// デバイス色空間を取得
ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);
// 描画オブジェクトを作成
paint = Paint.Create(outDoc, colorSpace, new double[] { 1.0, 0.0, 0.0 }, null);
// ページのコピーオプションを定義
PageCopyOptions copyOptions = new PageCopyOptions();
// 最初のページをコピーし、画像マスクを追加して出力ドキュメントに追加
Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
AddImageMask(outDoc, outPage, imageMaskPath, 250, 150);
outDoc.Pages.Add(outPage);
// 残りのページをコピーして出力ドキュメントに追加
PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
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およびPDF2.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 void AddImageMask(Document document, Page outPage, string imagePath,
double x, double y)
{
// コンテンツジェネレータを作成
using ContentGenerator generator = new ContentGenerator(outPage.Content, false);
// 入力パスからの画像読み込み
using Stream inImage = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
// 画像マスクオブジェクトを作成
ImageMask imageMask = ImageMask.Create(document, inImage);
double resolution = 150;
// 画像の矩形を計算
PdfTools.Toolbox.Geometry.Integer.Size size = imageMask.Size;
Rectangle rect = new Rectangle
{
Left = x,
Bottom = y,
Right = x + size.Width * 72 / resolution,
Top = y + size.Height * 72 / resolution
};
// 指定された四角形に画像マスクを描画
generator.PaintImageMask(imageMask, rect, paint);
}
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およびPDF2.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 add_image_mask(document: Document, page: Page, image_path: str, x: float, y: float):
# コンテンツジェネレータを作成
with ContentGenerator(page.content, False) as generator:
# 入力パスからの画像読み込み
with io.FileIO(image_path, 'rb') as in_image_stream:
# Create image mask object
image_mask = ImageMask.create(document, in_image_stream)
resolution = 150
# 画像の矩形を計算
size = image_mask.size
rect = Rectangle(
left=x,
bottom=y,
right=x + size.width * 72 / resolution,
top=y + size.height * 72 / resolution
)
# 指定された四角形に画像マスクを描画
generator.paint_image_mask(image_mask, rect, paint)
# 入力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)
# デバイス色空間を取得
color_space = ColorSpace.create_process_color_space(out_doc, ProcessColorSpaceType.RGB)
# 描画オブジェクトを作成
paint = Paint.create(out_doc, color_space, [1.0, 0.0, 0.0], None)
# ページのコピーオプションを定義
copy_options = PageCopyOptions()
# 最初のページをコピーし、画像マスクを追加して出力ドキュメントに追加
out_page = Page.copy(out_doc, in_doc.pages[0], copy_options)
add_image_mask(out_doc, out_page, image_mask_path, 250, 150)
out_doc.pages.append(out_page)
# 残りのページをコピーして出力ドキュメントに追加
in_page_range = in_doc.pages[1:]
copied_pages = PageList.copy(out_doc, in_page_range, copy_options)
out_doc.pages.extend(copied_pages)
既存PDFのページに線を描画します。
// 入力PDFを開く
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot cannot be opened. %s (ErrorCode: 0x%08x).\n"),
szInPath, szErrorBuff, Ptx_GetLastError());
// 出力PDFを作成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
szOutPath, szErrorBuff, Ptx_GetLastError());
// ドキュメント全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// コピーオプションを設定
pCopyOptions = PtxPdf_PageCopyOptions_New();
// 入力の全ページを繰り返す
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
_T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
for (int iPage = 1; iPage <= PtxPdf_PageList_GetCount(pInPageList); iPage++)
{
pInPage = PtxPdf_PageList_Get(pInPageList, iPage - 1);
// 入力から出力にページをコピー
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage,
_T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
PtxPdf_Page_GetSize(pOutPage, &size);
// 先頭のページにテキストを追加
if (addLine(pOutDoc, pOutPage) == 1)
{
goto cleanup;
}
// 出力ドキュメントにページを追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
_T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
if (pOutPage != NULL)
{
Ptx_Release(pOutPage);
pOutPage = NULL;
}
if (pInPage != NULL)
{
Ptx_Release(pInPage);
pInPage = NULL;
}
}
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// ビュワー設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル (PDF/A-3およびPDF 2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addLine(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdfContent_Path* pPath = NULL;
TPtxPdfContent_PathGenerator* pPathGenerator = NULL;
TPtxPdfContent_ColorSpace* pDeviceRgbColorSpace = NULL;
double aColor[3];
TPtxPdfContent_Paint* pPaint = NULL;
TPtxPdfContent_Stroke* pStroke;
TPtxGeomReal_Size pageSize;
TPtxGeomReal_Point point;
pContent = PtxPdf_Page_GetContent(pOutPage);
PtxPdf_Page_GetSize(pOutPage, &pageSize);
// コンテンツジェネレータを作成
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL(pGenerator, szErrorBuff, Ptx_GetLastError());
// パス(ベクターグラフィック)を作成
pPath = PtxPdfContent_Path_New();
GOTO_CLEANUP_IF_NULL(pPath, szErrorBuff, Ptx_GetLastError());
// パスジェネレータを作成
pPathGenerator = PtxPdfContent_PathGenerator_New(pPath);
GOTO_CLEANUP_IF_NULL(pPathGenerator, szErrorBuff, Ptx_GetLastError());
// ページ全体に斜めの線を描画
point.dX = 10.0;
point.dY = 10.0;
GOTO_CLEANUP_IF_FALSE(PtxPdfContent_PathGenerator_MoveTo(pPathGenerator, &point), szErrorBuff, Ptx_GetLastError());
point.dX = pageSize.dWidth - 10.0;
point.dY = pageSize.dHeight - 10.0;
GOTO_CLEANUP_IF_FALSE(PtxPdfContent_PathGenerator_LineTo(pPathGenerator, &point), szErrorBuff, Ptx_GetLastError());
// パスを終了するためにパスジェネレーターを閉じる
PtxPdfContent_PathGenerator_Close(pPathGenerator);
pPathGenerator = NULL;
// RGBカラースペースを作成
pDeviceRgbColorSpace =
PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
GOTO_CLEANUP_IF_NULL(pDeviceRgbColorSpace, szErrorBuff, Ptx_GetLastError());
// 赤色で初期化
aColor[0] = 1.0;
aColor[1] = 0.0;
aColor[2] = 0.0;
// 描画オブジェクトを作成
pPaint =
PtxPdfContent_Paint_Create(pOutDoc, pDeviceRgbColorSpace, aColor, sizeof(aColor) / sizeof(aColor[0]), NULL);
GOTO_CLEANUP_IF_NULL(pPaint, szErrorBuff, Ptx_GetLastError());
// 指定されたペイントと線幅でストロークパラメータを設定
pStroke = PtxPdfContent_Stroke_New(pPaint, 10.0);
GOTO_CLEANUP_IF_NULL(pStroke, szErrorBuff, Ptx_GetLastError());
// ページにパスを描画
GOTO_CLEANUP_IF_FALSE(PtxPdfContent_ContentGenerator_PaintPath(pGenerator, pPath, NULL, pStroke), szErrorBuff,
Ptx_GetLastError());
cleanup:
if (pPathGenerator != NULL)
PtxPdfContent_PathGenerator_Close(pPathGenerator);
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
// 入力PDFを開く
using (System.IO.Stream inStream = new System.IO.FileStream(inPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// 出力PDFを作成
using (System.IO.Stream outStream = new System.IO.FileStream(outPath, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// ドキュメント全体のデータをコピー
CopyDocumentData(inDoc, outDoc);
// ページコピーオプションを定義
PageCopyOptions copyOptions = new PageCopyOptions();
// 入力PDFからすべてのページをコピー
foreach (Page inPage in inDoc.Pages)
{
Page outPage = Page.Copy(outDoc, inPage, copyOptions);
// 線分をページに描画
AddLine(outDoc, outPage);
// ページを出力PDFに追加
outDoc.Pages.Add(outPage);
}
}
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およびPDF2.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 void AddLine(Document document, Page page)
{
// コンテンツジェネレータを作成
using ContentGenerator generator = new ContentGenerator(page.Content, false);
// パス(ベクターグラフィック)を作成
Path path = new Path();
using (PathGenerator pathGenerator = new PathGenerator(path))
{
// ページ全体に斜めの線を描画
Size pageSize = page.Size;
pathGenerator.MoveTo(new Point() { X = 10.0, Y = 10.0 });
pathGenerator.LineTo(new Point() { X = pageSize.Width - 10.0, Y = pageSize.Height - 10.0 });
}
// RGBカラースペースを作成
ColorSpace deviceRgbColorSpace = ColorSpace.CreateProcessColorSpace(document, ProcessColorSpaceType.Rgb);
// 赤色を作成
double[] color = new double[] { 1.0, 0.0, 0.0 };
// ペイントオブジェクトを作成
Paint paint = Paint.Create(document, deviceRgbColorSpace, color, null);
// 指定されたペイントと線幅でストロークパラメータを作成
Stroke stroke = new Stroke(paint, 10.0);
// ページにパスを描画
generator.PaintPath(path, null, stroke);
}
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およびPDF2.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 add_line(out_doc: Document, page: Page):
# コンテントジェネレータ
with ContentGenerator(page.content, False) as generator:
# パス(ベクターグラフィック)を作成
path = Path()
with PathGenerator(path) as path_generator:
# ページ全体に斜めの線を描画
page_size = page.size
path_generator.move_to(Point(x = 10.0, y = 10.0))
path_generator.line_to(Point(x = page_size.width - 10.0, y=page_size.height - 10.0))
# RGBカラースペースを作成
device_rgb_color_space = ColorSpace.create_process_color_space(out_doc, ProcessColorSpaceType.RGB)
# 赤色を作成
red = [1.0, 0.0, 0.0]
# ペイントオブジェクトを作成
paint = Paint.create(out_doc, device_rgb_color_space, red, None)
# 指定されたペイントと線幅でストロークパラメータを作成
stroke = Stroke(paint, 10.0)
# ページにパスを描画
generator.paint_path(path, None, stroke)
# 入力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()
# 入力PDFからすべてのページをコピー
for in_page in in_doc.pages:
out_page = Page.copy(out_doc, in_page, copy_options)
# 線分をページに描画
add_line(out_doc, out_page)
# ページを出力PDFに追加
out_doc.pages.append(out_page)
PDF文書の先頭ページの指定された位置にバーコードを生成して追加します。
// 入力ドキュメントを開く
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
szInPath, szErrorBuff, Ptx_GetLastError());
// フォントストリームを生成
pFontStream = _tfopen(szFontPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pFontStream, _T("Failed to open font file."));
PtxSysCreateFILEStreamDescriptor(&fontDescriptor, pFontStream, 0);
// 出力ドキュメントを生成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
szOutPath, szErrorBuff, Ptx_GetLastError());
pFont = PtxPdfContent_Font_Create(pOutDoc, &fontDescriptor, TRUE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// PDF全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// コピーオプション設定
pCopyOptions = PtxPdf_PageCopyOptions_New();
// 入出力ドキュメントのページリストを取得
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
_T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 先頭のページをコピー
pInPage = PtxPdf_PageList_Get(pInPageList, 0);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get the first page. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// コピーされたページにバーコード画像を追加
if (addBarcode(pOutDoc, pOutPage, szBarcode, pFont, 50) != 0)
goto cleanup;
// ページを出力ドキュメントに追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
_T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 残りのページを取得
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
_T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 取得した残りページを出力にコピー
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
_T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// コピーされたページを出力ファイルに追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
_T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// ビュワー設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル(PDF/A-3およびPDF2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addBarcode(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szBarcode, TPtxPdfContent_Font* pFont,
double dFontSize)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdfContent_Text* pBarcodeText = NULL;
TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
pContent = PtxPdf_Page_GetContent(pOutPage);
// コンテンツジェネレータを作成
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// Textオブジェクトを作成
pBarcodeText = PtxPdfContent_Text_Create(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pBarcodeText, _T("Failed to create a text object. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// Textジェネレータを作成
pTextGenerator = PtxPdfContent_TextGenerator_New(pBarcodeText, pFont, dFontSize, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 位置を計算
TPtxGeomReal_Size size;
PtxPdf_Page_GetSize(pOutPage, &size);
TPtxGeomReal_Point position;
double dTextWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szBarcode);
GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dTextWidth, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
double dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dFontAscent, _T("%s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
double dFontDescent = PtxPdfContent_Font_GetDescent(pFont);
GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dFontDescent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
position.dX = size.dWidth - (dTextWidth + dBorder);
position.dY = size.dHeight - (dFontSize * (dFontAscent + dFontDescent) + dBorder);
// 計算された位置に移動
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position),
_T("Failed to move to position %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// 指定されたバーコード文字列を追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szBarcode),
_T("Failed to add barcode string. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// Textジェネレータを終了
if (pTextGenerator != NULL)
PtxPdfContent_TextGenerator_Close(pTextGenerator);
// 位置指定されたバーコードテキストを描画
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pBarcodeText),
_T("Failed to paint the positioned barcode text. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
cleanup:
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
return iReturnValue;
}
// 入力ドキュメントを開く
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// ファイルストリームを生成
using (Stream fontStream = new FileStream(fontPath, FileMode.Open, FileAccess.Read))
// 出力ドキュメントを生成
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// PDF全体のデータをコピー
CopyDocumentData(inDoc, outDoc);
// 出力ドキュメントに埋め込みフォントを作成
Font font = Font.Create(outDoc, fontStream, true);
// ページのコピーオプションを定義
PageCopyOptions copyOptions = new PageCopyOptions();
// 先頭ページをコピーし、そこにバーコードを追加する。このページを出力ドキュメントに追加
Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
AddBarcode(outDoc, outPage, barcode, font, 50);
outDoc.Pages.Add(outPage);
// 残りのページをコピーして出力ドキュメントに追加
PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// PDF全体のデータをコピー
// 出力色特性設定
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およびPDF2.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 void AddBarcode(Document outputDoc, Page outPage, string barcode,
Font font, double fontSize)
{
// コンテンツジェネレータを作成
using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
// Textオブジェクトを作成
Text barcodeText = Text.Create(outputDoc);
// Textジェネレータを作成
using (TextGenerator textGenerator = new TextGenerator(barcodeText, font, fontSize, null))
{
// 位置を計算
Point position = new Point
{
X = outPage.Size.Width - (textGenerator.GetWidth(barcode) + Border),
Y = outPage.Size.Height - (fontSize * (font.Ascent + font.Descent) + Border)
};
// 計算された位置に移動
textGenerator.MoveTo(position);
// 与えられたバーコードテキストを追加
textGenerator.ShowLine(barcode);
}
// 位置指定されたバーコードテキストを描画
gen.PaintText(barcodeText);
}
def copy_document_data(in_doc: Document, out_doc: Document):
# PDF全体のデータをコピー
# 出力色特性設定
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およびPDF2.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 add_barcode(out_doc: Document, out_page: Page, barcode: str, font: Font, font_size: float):
# コンテンツジェネレータを作成
with ContentGenerator(out_page.content, False) as gen:
# Textオブジェクトを作成
barcode_text = Text.create(out_doc)
# Textジェネレータを作成
with TextGenerator(barcode_text, font, font_size, None) as text_generator:
# 位置を計算
position = Point(x=out_page.size.width - (text_generator.get_width(barcode) + border),
y=out_page.size.height - (font_size * (font.ascent + font.descent) + border))
# 計算された位置に移動
text_generator.move_to(position)
# 指定されたバーコード文字列を追加
text_generator.show_line(barcode)
# 位置指定されたバーコートテキストを描画
gen.paint_text(barcode_text)
# 境界を定義
border = 20
# 入力ドキュメントを開く
with io.FileIO(input_file_path, 'rb') as in_stream:
with Document.open(in_stream, None) as in_doc:
# フォントストリームを作成
with io.FileIO(font_path, 'rb') as font_stream:
# 出力ドキュメントを生成
with io.FileIO(output_file_path, 'wb+') as output_stream:
with Document.create(output_stream, in_doc.conformance, None) as out_doc:
# PDF全体のデータをコピー
copy_document_data(in_doc, out_doc)
# 出力ドキュメントに埋め込みフォントを作成
font = Font.create(out_doc, font_stream, True)
# ページのコピーオプションを定義
copy_options = PageCopyOptions()
# 先頭ページをコピーし、そこにバーコードを追加する。このページを出力ドキュメントに追加
out_page = Page.copy(out_doc, in_doc.pages[0], copy_options)
add_barcode(out_doc, out_page, barcode, font, 50.0)
out_doc.pages.append(out_page)
# 残りのページをコピーして出力ドキュメントに追加
in_page_range = in_doc.pages[1:]
copied_pages = PageList.copy(out_doc, in_page_range, copy_options)
out_doc.pages.extend(copied_pages)
他の機能サンプルを参照してください。
質問のページからお送りいただくようお願いします。
または、メールでsupport@trustss.co.jpあてにお送りください。
ご購入前の技術的質問も無償で対応します。サポート受付ページからお願いします。